[swift-evolution] Pitch: Import Objective-C Constants as Enums

Jeff Kelley slaunchaman at gmail.com
Mon Jan 18 11:13:09 CST 2016


I’ve got an in-progress proposal written up here:

https://github.com/SlaunchaMan/swift-evolution/blob/import-objc-constants/proposals/0000-import-objc-constants.md

I’ll leave it there for any additional comments/feedback, then submit later today.


Jeff Kelley

SlaunchaMan at gmail.com | @SlaunchaMan <https://twitter.com/SlaunchaMan> | jeffkelley.org <http://jeffkelley.org/>
> On Jan 18, 2016, at 9:52 AM, Jeff Kelley <SlaunchaMan at gmail.com> wrote:
> 
> Oh, that’s nice! Using the typedef would also allow Objective-C methods to be annotated with the type they expect while still allowing arbitrary strings for APIs where that’s necessary. Not only does that help in Swift—you wouldn’t have to use rawValue to pull the string values out when vending to the platform API—but it would give new developers to Apple platforms a head start on finding where those constants are defined in the headers.
> 
> I’ll write this up as a formal proposal using the typedef method, though I’m still all ears for any other comments/suggestions.
> 
> 
> Jeff Kelley
> 
> SlaunchaMan at gmail.com <mailto:SlaunchaMan at gmail.com> | @SlaunchaMan <https://twitter.com/SlaunchaMan> | jeffkelley.org <http://jeffkelley.org/>
>> On Jan 18, 2016, at 1:10 AM, Douglas Gregor <dgregor at apple.com <mailto:dgregor at apple.com>> wrote:
>> 
>>> 
>>> On Jan 17, 2016, at 7:13 PM, Jeff Kelley via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>> A lot of Cocoa APIs have long lists of constant values, typically NSStrings. I’d like to pitch a way to import them as enums with associated types. I can write up a full proposal if people think this is a good idea, but here’s my thinking:
>>> 
>>> Let’s take the error domains in NSError.h for a quick example. These entries in the header:
>>> 
>>>> FOUNDATION_EXPORT NSString *const NSCocoaErrorDomain;
>>>> FOUNDATION_EXPORT NSString *const NSPOSIXErrorDomain;
>>>> FOUNDATION_EXPORT NSString *const NSOSStatusErrorDomain;
>>>> FOUNDATION_EXPORT NSString *const NSMachErrorDomain;
>>> 
>>> 
>>> turn into this in the Swift interface:
>>> 
>>>> public let NSCocoaErrorDomain: String
>>>> public let NSPOSIXErrorDomain: String
>>>> public let NSOSStatusErrorDomain: String
>>>> public let NSMachErrorDomain: String
>>> 
>>> What I’m proposing is a way to import those as an enum instead. Similar to how we mark sections of Objective-C code with NS_ASSUME_NONNULL_BEGIN, we could mark it with something like NS_CASE_LIST_BEGIN. Then, this code:
>>> 
>>>> NS_CASE_LIST_BEGIN;
>>>> 
>>>> FOUNDATION_EXPORT NSString *const NSCocoaErrorDomain;
>>>> FOUNDATION_EXPORT NSString *const NSPOSIXErrorDomain;
>>>> FOUNDATION_EXPORT NSString *const NSOSStatusErrorDomain;
>>>> FOUNDATION_EXPORT NSString *const NSMachErrorDomain;
>>>> 
>>>> NS_CASE_LIST_END;
>>> 
>>> would be imported as follows:
>>> 
>>>> enum ErrorDomain : String {
>>>>     case Cocoa
>>>>     case POSIX
>>>>     case OSStatus
>>>>     case Mach
>>>> }
>>> 
>>> I can think of a lot of areas in Cocoa where these APIs could make things much more type-safe in Swift. Is this a good idea? Would people use this?
>> 
>> FWIW, this has come up a number of times in discussions among Swift developers (although not, IIRC, on swift-evolution). Our current favored way to write this in (Objective-)C would be with a new typedef of NSString * that has some special attribute on it, e.g.,
>> 
>>   typedef NSString * NSErrorDomain __attribute__((enum(string)));
>> 
>>   FOUNDATION_EXPORT NSErrorDomain const NSCocoaErrorDomain;
>>   FOUNDATION_EXPORT NSErrorDomain const NSPOSIXErrorDomain;
>>   FOUNDATION_EXPORT NSErrorDomain const NSOSStatusErrorDomain;
>>   FOUNDATION_EXPORT NSErrorDomain const NSMachErrorDomain;
>> 
>> The typedef would import as a String-backed enum and all of the string constants declared with that typedef within the same module as the typedef would become cases of that enum. String constants declared with that typedef in a *different* module would become “static lets” within extensions of the String-backed enum.
>> 
>> Call that a +1 from me on your idea :)
>> 
>> 	- Doug
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160118/30a6bce9/attachment.html>


More information about the swift-evolution mailing list