Posts

Post not yet marked as solved
0 Replies
317 Views
providing Codable support for a class. the class has an array that uses subclasses of the array's type. when you encode that sort of thing, you have to pull the array apart save individual arrays of each specific class, and then when you init that class, you will actually get the right Kind of type back. it's a security thing. I get it. but now... I have another wrinkle. the subclasses are going to be coming from plugins. now I can't know in advance, what the total list of possible subclasses are. what this all boils down to is: I can ask a class what it's type is: class.self but can I capture that? I can't find the type for dynamicType. I want to make an array of these types. I want to : add a String Identifier to my plugin, and ask the plugin, for a string Identifier for the Type. then I can save a dictionary of the subclasses, [String : [mySubClasses]] the String would be : myPlugin.subClassHint on Load, I should be able to cut up the string, I'll be able to find the plugin, and then ask for the type for that String... but I need to be able to Set the return Type. dynamicType... doesn't work. so, how do I refer to the dynamicType as a variable type? because... without it I've got no way to save data.
Posted
by eblu.
Last updated
.
Post marked as solved
3 Replies
1.3k Views
I have a protocol, in which I define a variable.public protocol CNEnvelopment { var pan : CGPoint {get set} var zoom : Float {get set} var dagObjs : [CNDagObj] {get set} // this one.I use that protocol type coerce another type, to shield myself from having to test the object type, and write about 30 lines of code for the same behavior in a series of classes:(theParent as! CNEnvelopment).dagObjs.insert(contentsOf: droppedItems, at: theIndex + 1)but I get an error when I do that:Cannot use mutating member on immutable value of type '[CNDagObj]'do I need to just throw the protocol away and use a class? Because it will work properly if I make CNEnvelopment a class. is this a limitation of protocols?
Posted
by eblu.
Last updated
.
Post not yet marked as solved
1 Replies
964 Views
updated to XCode 11.4then my app stopped compiling. this is the error:~/Library/Developer/Xcode/DerivedData/concrete-gbrhhoatnalnokezrxqmivnfpmuf/Build/Products/Debug/concrete.app: resource fork, Finder information, or similar detritus not allowedCommand CodeSign failed with a nonzero exit codeI'm fairly certain this error is not the real problem. my project has... 6 targets. 4 frameworks and desktop 2 applications. only happening to 1 application.I have cleaned all targets multiple times, tried rebooting, gone therough all targets and changed the names of folders named "Resources"logged out and back into my keychain, logged out and into of my account in XCode, turned off Signing altogether (or rather... I did the closest available thing,) changed the target OS version (started out at 10.14, went to 10.13, then 10.15)all random suggestions by random people on the internet.the app compiles, I can run it outside of Xcode. no problems. But it's not so finished that I can get by without actually debugging it.I've been through the project settings and compared them from the app that compiles and the app that ***** out. There's no obvious material difference.I think XCode is adding "resource fork, Finder information, or similar detritus" to my app, without my permission or my awareness.I'm at my wits end trying to track down the root cause for this compiler bug, that was inserted into my life with Xcode 11.4.help obi wan.-td
Posted
by eblu.
Last updated
.
Post marked as solved
2 Replies
557 Views
the docs are not helpful. in fact they don't seem to be indicating anything that works.so I'm hoping for a code example from someone who has been through this already.the context:I am writing a NSDraggingSource class. supporting the required method :func draggingSession(_ session: NSDraggingSession, sourceOperationMaskFor context: NSDraggingContext) -> NSDragOperation // we would like to respond with move and copy. let response : NSDragOperation = NSDragOperation.copy.rawValue | NSDragOperation.move.rawValue return response } as I noted, I want to provide 2 supported drag types: move, and copy.the docs say to do this:If the source permits dragging operations, the elements in the mask are one or more of the constants described in Obtaining Information About the Dragging Session, combined using the C bitwise OR operator.C Bitwise OR Operator is documented to be "|"Apple does not provide any notable examples of using this in the real world. the few 3rd party examples I have found look like this:let result2 = inputA | inputB print("Result after applying | operator:",result2)/* resultResult after applying | operator: 7 */// note: that example is worthless in this context. I wind up with a cascade of opaque errors with unhelpful suggestions.this is not something that can be guessed. It needs to be documented. it needs to be clear, and have multiple examples. Real ones. Not integers. Barring that tho... has anyone been through this, and can provide a straightforward example?
Posted
by eblu.
Last updated
.
Post not yet marked as solved
4 Replies
544 Views
so I have this challenge that keeps coming up. I solve it each time, but it's messy. I'd like to do it better.my classes derive from a protocol OR a superClass, but in this case it's a protocol.and the reason I have a hierarchy at all is that the classes have to handle different data similarly.so one of the central methods of the class (this is a for instance) is a method that converts the class's internal type to another type.func convert()->Stringa sibling class might need a similar method, but with a different return type:func convert()->Intthese classes are required to have a common ancestor (because their instances will eventually be in the same array.)But, I cannot define the 'convert' method in the protocol or the superclass, such that code addressing as yet unidentified specific type as it's superclass, can simply call the method:let myVar = classInstanceTreatedAsProtocolOrSuperClass.convert()I am instead, forced to do a switch:switch superClassObject{ case is ClassType: let myLet = (superClassObject as! ClassType).convert() whole list of things to do once we get that value case is OtherClassType: all of literally the same code pattern with the potential for slight differences due to type. ...}at times like this, with the Overabundance of required if and if let statements just to get through this, Swift goes from fun, to nightmarishly wordy. I would like to define, in my protocol, a method that defers the return type, but sets up teh method name, so that classes the partake of my protocol, can be expected to support that method. I don't think that's possible in swift. it may conflict with some of the behavior already in place... but I thoought I'd ask. It's no fun writing War and Peace, over and over again.
Posted
by eblu.
Last updated
.
Post not yet marked as solved
3 Replies
2.2k Views
in the tutorial I am following, which is for Swift 4.2 there is code, that when converted to my app's context looks like this:public enum PropertyFamily: String, ClassFamily { case CNStringProp = "CNStringProp" case CNIntProp = "CNIntProp" case CNBoolProp = "CNBoolProp" case CNFloatProp = "CNFloatProp" case CNClampedFloatProp = "CNClampedFloatProp" case CNColor_rgbaProp = "CNColor_rgbaProp" case CNPoint_xyProp = "CNPoint_xyProp" case CNSize_whProp = "CNSize_whProp" case CNSize_whdProp = "CNSize_whdProp" case CNVector_xyzProp = "CNVector_xyzProp" static var discriminator: Discriminator = .type func getType() -> AnyObject.Type { switch self { case .CNStringProp: return CNStringProp.self case .CNIntProp: return CNIntProp.self case .CNBoolProp: return CNBoolProp.self case .CNFloatProp: return CNFloatProp.self case .CNClampedFloatProp: return CNClampedFloatProp.self case .CNColor_rgbaProp: return CNColor_rgbaProp.self case .CNPoint_xyProp: return CNPoint_xyProp.self case .CNSize_whProp: return CNSize_whProp.self case .CNSize_whdProp: return CNSize_whdProp.self case .CNVector_xyzProp: return CNVector_xyzProp.self } } }this is an attempt to support saving Arrays with subclasses of a single class, without steamrolling the class type on load.everything that starts with 'CN' is an NSObject subclass. the goal of the enum is to load a String property and turn it into a class type that can be used per record while loading an array.there is a protocol that defines ClassFamily (supplied by the tutorial):/// To support a new class family, create an enum that conforms to this protocol and contains the different types. protocol ClassFamily: Decodable { /// The discriminator key. static var discriminator: Discriminator { get } /// Returns the class type of the object coresponding to the value. func getType() -> AnyObject.Type } /// Discriminator key enum used to retrieve discriminator fields in JSON payloads. enum Discriminator: String, CodingKey { case type = "type" }I'm learning as I go, but I've hit a snag. I suspect that it's an issue that comes from Swift 4.2 moving to Swift 5on return in the 'getType' function I have an error that states: 'Enum case 'ClassName' cannot be used as an instance member'there is a 'fix it' button. and when that happens,this: return CNSize_whProp.selfturns into this : return PropertyFamily.CNSize_whProp.selfwhich sets off even worse errors:'Cannot convert return expression of type 'PropertyFamily' to return type 'AnyObject.Type''I know the compiler is barking up the wrong tree. What it transforms the code into is gibberish. What I do not know, is what the real problem is. The example is explicit, but it does not go into any detail about how to handle the AnyObject.type type when things go wrong.
Posted
by eblu.
Last updated
.
Post marked as solved
3 Replies
660 Views
I can do this with a Float or a Double, but I'm curious...can I define a new property type?the general idea is to make a new Kind of float that is limited to values > 0 & < 1.creating a normalized float.I could build it as a structure:struct normalizedFloat { var value: Float{ get{return internalValue} set{ internalValue = Float.minimum(Float.maximum(value, 0), 1) } } var internalValue : Float = 0 }but that creates extra work any time a 'normalized float' comes up in the data...var norm : normalizedFloat = normalizedFloat(value : 0.123)instead of : var norm : normalizedFloat = 0.124I have some experience overloading operators, by no means am I an expert at that... but this seems 'next level' compared to that. what kinds of search terms should I use to find out more? is it even possible?
Posted
by eblu.
Last updated
.
Post marked as solved
3 Replies
589 Views
I have a framework. this is the entire thing:import Foundation public let BKNoteChangeAdd : String = "BKNoteChangeAdd" public let BKNoteChangeRemove : String = "BKNoteChangeRemove" public let BKNoteChangeSet : String = "BKNOteChangeSet" public protocol BKNotifier{ func registerForNotes(observer: NSObject) func unregisterForNotes(observer: NSObject) func updateRegisteredObservers(_ key: String, change: [String : [Any]], objectPath : [BKNotifier]) } public protocol BKObserver{ func objectChanged(_ objectPath: [BKNotifier] , key: String, change : [String : [Any]]) }it defines 2 protocols.this framework is built ina different project than the one I am currently working on.I would have rather installed it on the machine and just imported it into my project that way, but there's nothing detailing how to do that, and it's clearly not automatic. So instead, I am adding it to my project.I drag the product from XCode's file list to my current project.(i Have now done this dozens of times)I discovered that a change was necessary in order to get my protocol to work in the new context... registerForNotes and unregisterForNotes' observer property was AnyObject. It is required to be NSObject to work inside of a struct... I can't explain it, I didn't set the limitations... AnyClass doesn't work, But NSObject does. I am not put out by that at all. But, when I made the change in my framework, and recompiled, and deleted and re-dragged, and imported the framework into my new framework...I get error messages that my class does not conform to BKNotifier, here's those two methods:public mutating func registerForNotes(observer: NSObject) { if observer is BKObserver && regObjs.contains(observer) == false{ regObjs.append(observer) } } public mutating func unregisterForNotes(observer: NSObject) { if let anIndex = self.regObjs.firstIndex(of: observer){ self.regObjs.remove(at: anIndex) } }and if I let the editor make stubs for conforming to BKNotifier I get this: public func registerForNotes(observer: AnyObject) { <#code#> } public func unregisterForNotes(observer: AnyObject) { <#code#> }I tried AnyObject precisely 1 time. yet I can completely remove all references to the framework, remove all framework related code, clean the BKNote framework's compile, and recompile, re-do everything... from scratch... and it still throws this error.what else can I try?
Posted
by eblu.
Last updated
.
Post not yet marked as solved
2 Replies
518 Views
I am having some difficulty getting started with this feature.my project is a framework, And It's time to test soem of the things I'm doing in that framework.I saw that I could add a playground to my project, and I thought that was exactly what I needed. I added a new playground to my project, imported my framework, compiled that framework, and nothing works. Is this not what it's meant for? Does it just plain not work like that? or have I missed something?
Posted
by eblu.
Last updated
.
Post not yet marked as solved
7 Replies
827 Views
so... it's impractical and just a bit too much to post the code... it's an entire app, several frameworks, and well... a LOT of code. So I'm hoping for some more general advice on this one.I am getting an error message of : Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional valueat a very wierd spot.on the first case of a switch, where the item being switched is NOT an optional.The property being switched is a String, and I can see it in the debugger: It's not optional and it != nil.I figured I was facing a recursion issue, but I've learned how to recognise them in the debugger, and nope. Not recursion (no irrevocable loop here)Here's what I most recently did to my app: I unembedded a View from a tabView in InterfaceBuilder, and had to re-connect 3 outlets.the error I am getting is specific to making a selection of a model object. (which is the same thing as adding it to an array.) so the error, is not telling me what's going wrong, and it's at a very wierd place that cannot possibly be the issue, and I am at a loss. there's no indication of _any_ optionals at all in this part of the app.
Posted
by eblu.
Last updated
.
Post not yet marked as solved
1 Replies
484 Views
I know this is a long shot. and I've looked at the docs, and it doesn't seem like its a possibility. But I figured I'd ask here just in case I didn't see something important.I have recently added NSNumberFormatter to my workflow, and it works great for most things. There's just one instance where it doesn't seem to have capability.and that's formatting the display of Arrays of numbers.for instance:let arr = [0.0, 3.4, 6.6, 9.99, 124.0]might display as :0.0 - 124.0I have a solution, that works great. but it's an either or proposition. I can't use NSNumber formatter AND my solution. I have to choose. and frankly: NSNumberFormatter is very convenient. So... is there a special class of number formatter that Might be able to handle this kind of Number transform to String? or am I right in assuming that no... number formatters aren't intended to work like that?
Posted
by eblu.
Last updated
.
Post not yet marked as solved
8 Replies
1.8k Views
this happens to be in the context of UserDefaults. I'm trying to track down an issue where a particular class is turned into it's superclass, either when saving to UserDefaults, or loading from UserDefaults.the classes in question (the super class and the class that gets 'permanently coerced') are for all purposes have the same footprint in storage. Same properties. Just different behavior after being loaded. What is saved to UserDefaults is a Data object constructed from an array.the array is defined as an array of the superclass type:var items : [BKLayerController]the saving and the loading code:open var items : [BKLayerController] { get{ var theObjs : [BKLayerController] = [] if let theData = UserDefaults.standard.data(forKey: BKToolboxDefaults) as? Data{ do { theObjs = try PropertyListDecoder().decode([BKLayerController].self, from: theData) } catch { debugPrint(error) } } return theObjs } set{ do { let theData = try PropertyListEncoder().encode(newValue) UserDefaults.standard.set(theData, forKey: BKToolboxDefaults) } catch { debugPrint(error) } } }the Defaults registration code: let layer = BKLayerController() layer.name = "layer" let textLayer = BKTextLayerCon() textLayer.name = "textLayer" do { let theData = try PropertyListEncoder().encode([layer,textLayer]) UserDefaults.standard.register(defaults: [BKToolboxDefaults : theData ]) } catch { }the class "BKTextLayerCon"is a "BKLayerController" class (it's super class) upon loading of the Defaults. It may happen during the saving process, I still haven't figured out how to test that yet.my question, is that when you load objects with the propertyListDecoder (and with Codable Decoders in general) do you need to specify specific types? If so, what would that look like? like this?if let theData = UserDefaults.standard.data(forKey: BKToolboxDefaults) as? Data{ do { theObjs = try PropertyListDecoder().decode([[BKLayerController].self, [BKTextLayerCon].self], from: theData) } catch { debugPrint(error) } }
Posted
by eblu.
Last updated
.