<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">One note to those constants; there are a number of them (NSError domains in particular) that are intended to be a complement to the application space defines; such that your app could define a “MyGreatAppErrorDomain” and a “MyGreatFrameworkErrorDomain” in addition to the NSCocoaErrorDomain. So this isn’t exactly an enum but more so a non closed set of values. Enums are usually closed sets so that they can be switched upon exhaustively. Others would definitely improve the state of affairs for both objc and swift in that technically you could get a warning/error in objc if the type was not correct and there would be the swift ramifications you mentioned as well.</div><div class=""><br class=""></div><div class="">Examples:</div><div class=""><br class=""></div><div class="">@interface NSError : NSObject <NSCopying, NSSecureCoding></div><div class="">…</div><div class="">- (instancetype)initWithDomain:(NSErrorDomain)domain code:(NSInteger)code userInfo:(nullable NSDictionary *)dict</div><div class="">…</div><div class="">@end</div><div class=""><br class=""></div><div class="">this would mean that the following code would not work (or should produce a warning)</div><div class="">[[NSError alloc] initWithDomain:@“MyAppDomain” code:42 userInfo:nil];</div><div class=""><br class=""></div><div class="">moreover in swift:</div><div class="">NSError(“MyAppDomain”, code:42, userInfo:nil) // would this even work?</div><div class=""><br class=""></div><div class="">On the other hand it might be useful for the (desperately in need of some updating) NSLocale method</div><div class=""><br class=""></div><div class="">@interface NSLocale : NSObject <NSCopying, NSSecureCoding><br class="">...<br class="">- (nullable id)objectForKey:(NSLocaleKey)key; // we could limit the keys accepted here to just the appropriate values in the “enum"</div><div class="">...</div><div class="">@end</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">From a brief survey of the APIs this would be useful for they mostly seem to be “dictionary based programming” cases which expose poorly in swift because they don’t have type safe return values. Adding more swift-friendly interfaces to those APIs is not off the table; because it is not just the keys that are the issue here but the return values too (see NSLocale’s example). Not to say we couldn’t do both, but would it be the case that if the un-typed return values that access by keys are replaced with better, more safe interfaces, this still be needed?</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 18, 2016, at 9:13 AM, Jeff Kelley via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I’ve got an in-progress proposal written up here:</div><div class=""><br class=""></div><div class=""><a href="https://github.com/SlaunchaMan/swift-evolution/blob/import-objc-constants/proposals/0000-import-objc-constants.md" class="">https://github.com/SlaunchaMan/swift-evolution/blob/import-objc-constants/proposals/0000-import-objc-constants.md</a></div><div class=""><br class=""></div><div class="">I’ll leave it there for any additional comments/feedback, then submit later today.</div><div class=""><br class=""></div><br class=""><div class="">
<div style="font-family: Helvetica; font-style: normal; font-variant-ligatures: normal; font-variant-position: normal; font-variant-caps: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="font-family: Helvetica; font-style: normal; font-variant-ligatures: normal; font-variant-position: normal; font-variant-caps: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="font-family: Helvetica; font-style: normal; font-variant-ligatures: normal; font-variant-position: normal; font-variant-caps: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; line-height: normal; border-spacing: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; " class=""><div class="">Jeff Kelley</div><div class=""><br class=""></div><div class=""><a href="mailto:SlaunchaMan@gmail.com" class="">SlaunchaMan@gmail.com</a> | <a href="https://twitter.com/SlaunchaMan" class="">@SlaunchaMan</a> | <a href="http://jeffkelley.org/" class="">jeffkelley.org</a></div></div></span></div></div></div>
</div>
<br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 18, 2016, at 9:52 AM, Jeff Kelley <<a href="mailto:SlaunchaMan@gmail.com" class="">SlaunchaMan@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">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.</div><div class=""><br class=""></div><div class="">I’ll write this up as a formal proposal using the typedef method, though I’m still all ears for any other comments/suggestions.</div><div class=""><br class=""></div><br class=""><div class="">
<div style="font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class="Apple-style-span" style="border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; border-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px;"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; " class=""><div class="">Jeff Kelley</div><div class=""><br class=""></div><div class=""><a href="mailto:SlaunchaMan@gmail.com" class="">SlaunchaMan@gmail.com</a> | <a href="https://twitter.com/SlaunchaMan" class="">@SlaunchaMan</a> | <a href="http://jeffkelley.org/" class="">jeffkelley.org</a></div></div></span></div></div></div>
</div>
<br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 18, 2016, at 1:10 AM, Douglas Gregor <<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Jan 17, 2016, at 7:13 PM, Jeff Kelley via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">A lot of Cocoa APIs have long lists of constant values, typically<span class="Apple-converted-space"> </span><font face="Menlo" class="">NSString</font>s. I’d like to pitch a way to import them as<span class="Apple-converted-space"> </span><font face="Menlo" class="">enum</font>s with associated types. I can write up a full proposal if people think this is a good idea, but here’s my thinking:</div><div class=""><br class=""></div><div class="">Let’s take the error domains in<span class="Apple-converted-space"> </span><font face="Menlo" class="">NSError.h</font><span class="Apple-converted-space"> </span>for a quick example. These entries in the header:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""><blockquote type="cite" class="">FOUNDATION_EXPORT NSString *const NSCocoaErrorDomain;<br class="">FOUNDATION_EXPORT NSString *const NSPOSIXErrorDomain;<br class="">FOUNDATION_EXPORT NSString *const NSOSStatusErrorDomain;<br class="">FOUNDATION_EXPORT NSString *const NSMachErrorDomain;</blockquote></font></div><div class=""><br class=""></div><div class="">turn into this in the Swift interface:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""></font></div><blockquote type="cite" class=""><div class=""><font face="Menlo" class="">public let NSCocoaErrorDomain: String<br class="">public let NSPOSIXErrorDomain: String<br class="">public let NSOSStatusErrorDomain: String<br class="">public let NSMachErrorDomain: String</font></div></blockquote><div class=""><br class=""></div><div class="">What I’m proposing is a way to import those as an<span class="Apple-converted-space"> </span><font face="Menlo" class="">enum</font><span class="Apple-converted-space"> </span>instead. Similar to how we mark sections of Objective-C code with<span class="Apple-converted-space"> </span><font face="Menlo" class="">NS_ASSUME_NONNULL_BEGIN</font>, we could mark it with something like<span class="Apple-converted-space"> </span><font face="Menlo" class="">NS_CASE_LIST_BEGIN</font>. Then, this code:</div><div class=""><br class=""></div><div class=""></div><blockquote type="cite" class=""><div class=""><font face="Menlo" class="">NS_CASE_LIST_BEGIN;</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">FOUNDATION_EXPORT NSString *const NSCocoaErrorDomain;<br class="">FOUNDATION_EXPORT NSString *const NSPOSIXErrorDomain;<br class="">FOUNDATION_EXPORT NSString *const NSOSStatusErrorDomain;<br class="">FOUNDATION_EXPORT NSString *const NSMachErrorDomain;</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">NS_CASE_LIST_END;</font></div></blockquote><div class=""><br class=""></div><div class="">would be imported as follows:</div><div class=""><br class=""></div><font face="Menlo" class=""></font><div class=""></div><blockquote type="cite" class=""><font face="Menlo" class="">enum ErrorDomain : String {<br class=""> case Cocoa<br class=""> case POSIX<br class=""> case OSStatus</font><div class=""><font face="Menlo" class=""> case Mach<br class="">}</font></div></blockquote><div class=""><br class=""></div><div class="">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?<br class=""></div></div></div></blockquote></div><br class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">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.,</div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> typedef NSString * NSErrorDomain __attribute__((enum(string)));</div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> FOUNDATION_EXPORT NSErrorDomain const NSCocoaErrorDomain;</div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""> FOUNDATION_EXPORT NSErrorDomain const NSPOSIXErrorDomain;</div></div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""> FOUNDATION_EXPORT NSErrorDomain const NSOSStatusErrorDomain;</div></div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""> FOUNDATION_EXPORT NSErrorDomain const NSMachErrorDomain;</div></div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">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.</div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Call that a +1 from me on your idea :)</div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: HelveticaNeue; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><span class="Apple-tab-span" style="white-space: pre;">        </span>- Doug</div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>