Secure coding NSArray
I might be late to this party, but since I just spent hours on it, I’ll document this for anyone who hasn’t run into it yet. If you’re using NSSecureCoding, there’s a problem decoding NSArray objects. You can’t use this: myArray = [coder decodeObjectForKey: @“myArray”]; and you can’t use this: myArray = [coder decodeObjectOfClass: [NSArray class] forKey: @“myArray”]; The error message in the resulting exception won’t be very helpful, but it means that the class of the array elements is invalid. What you actually need to do is this: myArray = [coder decodeObjectOfClasses: [NSSet setWithObjects: [NSArray class], [MyElementClass class], nil] forKey: @“myArray”]; Besides being obscure, this is also semantically incorrect, in that it appears to allow decoding of objects that are not strictly arrays of MyElementClass objects. (I guess this is not a security violation, since it doesn’t permit an attack to substitute objects of arbitrary classes, but it sure is annoying.] Now, if you want to do this in Swift, you might be tempted to try the obvious translation: let classes = Set (arrayLiteral: [… anything here… ]) let myArray = coder.decodeObjectOfClasses (classes, forKey: “myArray”) but that won’t work because AnyClass isn’t Hashable. So you might try (well, I tried) something like this: let classes = Set (arrayLiteral: [NSArray.self, MyElementClass.self]) let myArray = coder.decodeObjectOfClasses (classes, forKey: “myArray”) This compiles, but it fails at run-time, with a message saying it found an object of class ‘NSArray’, but only objects of classes ‘NSArray’ and ‘MyElementClass’ are allowed. (!) The solution is to fall back to an explicit NSSet object: let classes = NSSet (objects: NSArray.self, MyElementClass.self) let myArray = coder.decodeObjectOfClasses (classes, forKey: “myArray”) There really needs to be (radar #24646135) API to decode a NSArray and specify the class (or classes) of the elements. In Obj-C, something like: myArray = [coder decodeArrayWithObjectsOfClass: [MyElementClass class] forKey: @“myArray”]; or in Swift: let myArray = coder.decodeArrayWithObjectsOfClass (MyElementClass.self, forKey: “myArray”) This would be particular useful in Swift, because it would give you compile-time checking of the types in the assignment. (There is already a Swift-only version of ‘decodeObjectOfClass’ that’s generic, so you get the “correct” return type.) ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Swift bindings issue, Swift.Dictionary, NSMutableDictionary and NSObjectController
I have a .xib with a NSObjectController with it's content bound to a Swift [String : AnyObject] variable, but get the following error: *Cocoa Bindings: Error setting value for key path selection.startDate of object [object class: NSMutableDictionary] (from bound object ): [<_TtGCSs29_NativeDictionaryStorageOwnerSSPSs9AnyObject__ 0x61423da0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key startDate.* 1/ Is this reasonable? 2/ Should I prefer NSMutableDictionary in the Swift code? Thanks. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Deleting an file that's been NSData memory mapped - safe?
> On 11 Feb 2016, at 20:44, Dan Lau wrote: > > If a file has its contents mapped using NSData's > initWithContentsOfFile + NSDataReadingMappedIfSafe, > deleting it doesn't appear to affect reading it's mapped contents. Does > anyone know if NSData uses mmap(2) under the hood to ensure that this sort > of operation is valid? [As Jens said: yes] In fact, file data will stick around as long as you have an open file descriptor or a mapping. A neat trick for temporary files that you want to make sure get cleaned up is to open() and unlink() immediately afterward. The file data will be automatically deleted when your process exits. Marcel ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Deleting an file that's been NSData memory mapped - safe?
> On Feb 14, 2016, at 7:17 PM, Marcel Weiher wrote: > > >> On 11 Feb 2016, at 20:44, Dan Lau wrote: >> >> If a file has its contents mapped using NSData's >> initWithContentsOfFile + NSDataReadingMappedIfSafe, >> deleting it doesn't appear to affect reading it's mapped contents. Does >> anyone know if NSData uses mmap(2) under the hood to ensure that this sort >> of operation is valid? > > [As Jens said: yes] > > In fact, file data will stick around as long as you have an open file > descriptor or a mapping. > > A neat trick for temporary files that you want to make sure get cleaned up is > to open() and unlink() immediately afterward. > > The file data will be automatically deleted when your process exits. > > Marcel > > > ___ > > / Would the file itself be accessible by another process before your process exits? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Deleting an file that's been NSData memory mapped - safe?
> On 14 Feb 2016, at 11:45, dangerwillrobinsondan...@gmail.com wrote: > > Would the file itself be accessible by another process before your process > exits? Only if it manages to open it before it gets unlinked. After it gets unlinked, there’s no way to open it because there’s no longer any associated filename. Chris ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift bindings issue, Swift.Dictionary, NSMutableDictionary and NSObjectController
> On Feb 14, 2016, at 2:06 AM, Samuel Williams > wrote: > > 2/ Should I prefer NSMutableDictionary in the Swift code? It looks like you’ll need to use Foundation collection classes, for properties that you want to bind in this way. Remember, Swift’s native arrays and dictionaries aren’t toll-free bridged to NSArray and NSDictionary, so you can’t always use them interchangeably. They’re just copied to/from Foundation objects on demand, by the compiler. But binding doesn’t happen at compile time, so at runtime you end up with the key-value-coding implementation trying to operate on a native Swift object it doesn’t understand. —Jens ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift bindings issue, Swift.Dictionary, NSMutableDictionary and NSObjectController
On Feb 14, 2016, at 02:06 , Samuel Williams wrote: > > 2/ Should I prefer NSMutableDictionary in the Swift code? Is your Swift property declared ‘dynamic’. Also, keep in mind that the Swift type that’s bridgeable to NSDictionary is [NSObject, AnyObject]. Your type [String, ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift bindings issue, Swift.Dictionary, NSMutableDictionary and NSObjectController
(sorry about the previous post, hit Send early by accident) On Feb 14, 2016, at 02:06 , Samuel Williams mailto:space.ship.travel...@gmail.com>> wrote: > > 2/ Should I prefer NSMutableDictionary in the Swift code? Is your Swift property declared ‘dynamic’? Also, keep in mind that the Swift type that’s bridgeable to NSDictionary is [NSObject: AnyObject]. Your type [String: AnyObject] can be upcast to a bridgeable type, but things get a bit murky about what’s supposed to happen when. Also, I recommend that you do *not* use a mutable dictionary as a cheap replacement for a class with its own properties. It may seem like a good shortcut, but it’s going to have limitations (perhaps unrelated to the current problem) when you start binding to it. ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Swift bindings issue, Swift.Dictionary, NSMutableDictionary and NSObjectController
Yeah, the easiest solution was to not use a dictionary but use a class, which copied the data into the dictionary. Here is the top level sheet: class PMSRConfigurationSheet: NSWindowController { dynamic var metadata: [String : AnyObject] = [String : AnyObject]() override class func keyPathsForValuesAffectingValueForKey(key: String) -> Set { if (key != "metadata") { return ["metadata"] } else { return [] } } @IBOutlet var objectController: NSObjectController? @IBAction func apply(sender: AnyObject?) { objectController?.commitEditing() if let window = self.window { if let sheetParent = window.sheetParent { sheetParent.endSheet(window, returnCode: NSModalResponseContinue) } } } @IBAction func cancel(sender: AnyObject?) { objectController?.discardEditing() if let window = self.window { if let sheetParent = window.sheetParent { sheetParent.endSheet(window, returnCode: NSModalResponseAbort) } } } } Here is the actually subclass with some properties: @objc(PMSRExpenseReportConfigurationSheet) class PMSRExpenseReportConfigurationSheet: PMSRConfigurationSheet { dynamic var startDate: NSDate? { get { return self.metadata["startDate"] as? NSDate } set(value) { self.metadata["startDate"] = value } } dynamic var endDate: NSDate? { get { return self.metadata["endDate"] as? NSDate } set(value) { self.metadata["endDate"] = value } } override init(window: NSWindow?) { super.init(window: window) } required init?(coder: NSCoder) { super.init(coder: coder) } init() { self.init(windowNibName: "PMSRExpenseReportConfigurationSheet") } override func apply(sender: AnyObject?) { print("Date range: \(self.startDate) -> \(self.endDate)") super.apply(sender) } } Works perfectly! ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com