+1.  This is fantastic.

> On Aug 23, 2016, at 5:36 PM, Douglas Gregor via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Introduction
> 
> A handful of Swift numeric types are bridged to NSNumber when passed into 
> Objective-C object contexts. We should extend this bridging behavior to all 
> Swift numeric types. We should also bridge common Cocoa structs such as 
> NSRangeby boxing them into NSValue objects.
> 
> Swift-evolution thread: TBD 
> <https://lists.swift.org/pipermail/swift-evolution/>
>  
> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-nsnumber-and-nsvalue.md#motivation>Motivation
> 
> SE-0116 
> <https://github.com/apple/swift-evolution/blob/master/proposals/0116-id-as-any.md>
>  changed how Objective-C's id and untyped collections import into Swift to 
> use the Any type. This makes it much more natural to pass in Swift value 
> types such as String and Array, but introduces the hazard of passing in types 
> that don't bridge well to Objective-C objects. Particularly problematic are 
> number types; whereas Int, UInt, and Double will automatically bridge as 
> NSNumber, other-sized numeric types fall back to opaque boxing:
> 
> let i = 17
> let plist = ["seventeen": i]
> // OK
> try! NSJSONSerialization.data(withJSONObject: plist)
> 
> let j: UInt8 = 38
> let brokenPlist = ["thirty-eight": j]
> // Will throw because `j` didn't bridge to a JSON type
> try! NSJSONSerialization.data(withJSONObject: brokenPlist)
> We had shied away from enabling this bridging for all numeric types in the 
> Swift 1.x days, among other reasons because we allowed implicit bridging 
> conversions in both directions from Swift value types to NS objects and back, 
> which meant that you could slowly and brokenly convert between any two 
> numeric types transitively via NSNumber if we allowed this. We killed the 
> implicit conversions completely with SE-0072 
> <https://github.com/apple/swift-evolution/blob/master/proposals/0072-eliminate-implicit-bridging-conversions.md>
>  so that is no longer a concern, so expanding the bridging behavior should no 
> longer be a major problem, since it must now always be explicitly asked for.
> 
> There are also many Cocoa APIs that accept NSArray and NSDictionary objects 
> with members that are NSValue-boxed structs. Matt Neuberg highlights Core 
> Automation as an example in this bug report 
> <https://bugs.swift.org/browse/SR-2414>. With id-as-Any, it's natural to 
> expect this to work:
> 
> anim.toValue = CGPoint.zero
> However, the CGPoint value does not box as a meaningful Objective-C object, 
> so this currently breaks Core Animation at runtime despite compiling 
> successfully. It would be more idiomatic to bridge these types to NSValue.
> 
>  
> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-nsnumber-and-nsvalue.md#proposed-solution>Proposed
>  solution
> 
> All of Swift's number types should be made to bridge to NSNumber when used as 
> objects in Objective-C:
> 
> Int8
> Int16
> Int32
> Int64
> UInt8
> UInt16
> UInt32
> UInt64
> Float
> Double
> Cocoa structs with existing NSValue factory and property support should be 
> made to bridge to NSValue when used as objects:
> 
> NSRange
> CGPoint
> CGVector
> CGSize
> CGRect
> CGAffineTransform
> UIEdgeInsets
> UIOffset
> CATransform3D
> CMTime
> CMTimeRange
> CMTimeMapping
> MKCoordinate
> MKCoordinateSpan
> SCNVector3
> SCNVector4
> SCNMatrix4
>  
> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-nsnumber-and-nsvalue.md#detailed-design>Detailed
>  design
> 
> Bridged NSNumber and NSValue objects must be castable back to their original 
> Swift value types. NSValue normally preserves the type information of its 
> included struct in its objCType property. We can check the objCType of an 
> NSValue instance when attempting to cast back to a specific bridged struct 
> type.
> 
> NSNumber is a bit trickier, since Cocoa's implementation does not generally 
> guarantee to remember the exact number type an instance was constructed from. 
> We can instead say that casting an NSNumber to a Swift number type succeeds 
> if the value of the NSNumber is exactly representable as the target type. 
> This is imperfect, since it means that an NSNumbercan potentially be cast to 
> a different type from the original value, but it at least ensures that Swift 
> values round-trip through the bridge without depending on NSNumber 
> implementation details.
> 
>  
> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-nsnumber-and-nsvalue.md#impact-on-existing-code>Impact
>  on existing code
> 
> This change has no static source impact, but changes the dynamic behavior of 
> the Objective-C bridge. From Objective-C's perspective, values that used to 
> bridge as opaque objects will now come in as semantically meaningful 
> Objective-C objects. This should be a safe change, since existing code should 
> not be relying on the behavior of opaque bridged objects. From Swift's 
> perspective, values should still be able to round-trip from concrete number 
> and struct types to Anyto id to Any and back by dynamic casting. The ability 
> to reliably distinguish the exact number type that an NSNumberwas constructed 
> from would be lost.
> 
>  
> <https://github.com/jckarter/swift-evolution/blob/be49e08f56450ffea394306198bcd25f58915e30/proposals/XXXX-bridge-nsnumber-and-nsvalue.md#alternatives-considered>Alternatives
>  considered
> 
> We can of course do nothing and leave the behavior as-is.
> 
> NSValue also carries factories for valueWithPointer: and 
> valueWithNonretainedObject:. Maybe we could bridgeUnsafePointer and Unmanaged 
> this way, but we probably shouldn’t.
> 
>       - Doug
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to