<div dir="ltr">I updated my <a href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md">proposal</a> to reflect the community&#39;s desire to build on @objc instead of adding a new attribute @objcstring.<div><br></div><div>I&#39;ve included it below for convenience:</div><div><br></div><div><h1 style="box-sizing:border-box;margin:0px 0px 16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;">Swift Enum strings ported to Objective-c</h1><ul style="box-sizing:border-box;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px"><li style="box-sizing:border-box">Proposal: <a href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-filename.md" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none">SE-NNNN</a></li><li style="box-sizing:border-box;margin-top:0.25em">Authors: <a href="https://github.com/wh1pch81n" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none">Derrick Ho</a></li><li style="box-sizing:border-box;margin-top:0.25em">Review Manager: TBD</li><li style="box-sizing:border-box;margin-top:0.25em">Status: <span style="box-sizing:border-box;font-weight:600">Awaiting review</span></li></ul><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px"><em style="box-sizing:border-box">During the review process, add the following fields as needed:</em></p><ul style="box-sizing:border-box;padding-left:2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px"><li style="box-sizing:border-box">Decision Notes: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161114/028950.html" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none">Rationale</a></li><li style="box-sizing:border-box;margin-top:0.25em">Previous Proposal: <a href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/0033-import-objc-constants.md" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none">SE-0033</a></li></ul><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-introduction" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#introduction" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Introduction</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">We should allow swift-enum-strings and swift-struct-strings to be bridged to objective-c. We can use the following notation:</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">@objc enum Planets: String { case Mercury }</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">@objc struct Food: String { public static let hamburger = Food(rawValue: &quot;hamburger&quot;) }</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">Creating a bridgable version will allow objective-c to enjoy some of the benefits that swift enjoys. </p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">Swift-evolution thread: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161114/028950.html" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none">Discussion</a> <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170220/032656.html" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none">Discussion</a></p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-motivation" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#motivation" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Motivation</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">NS_STRING_ENUM and NS_EXSTENSIBLE_STRING_ENUM are annotations that you can add to an objective-c global string. The annotations will make swift interpret the objective-c global strings as enum and structs respectively in theory. But it actually <a href="https://bugs.swift.org/browse/SR-3146" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none">doesn&#39;t ever create enums</a>.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">The problem seems to stem from the conversion from objc to swift. It might be more fruitful to make a conversion from swift to objc.</p><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">However, what if we take it a step further? Turning a swift-string-enum into a bunch of global NSStrings really limits its power. There are many classes written by apple that are structs in swift but become classes in objective-c (i.e. String becomes NSString, Date becomes NSDate, Array becomes NSArray, etc). There is a special bridging mechanism that allows this to be possible. I think we should expand on that.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-proposed-solution" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#proposed-solution" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Proposed solution</h2><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// `@objc` and `String` can be applied to an enum to make it available to objective-c:
//
@objc
public enum Food: String {
   case Calamari 
   case Fish


// This can be ported over to Objective-c as an objective-c class

@interface Food: NSObject

@property (readonly) NSString *_Nonnull rawValue;

- (instancetype _Nullable)initWithRawValue:(NSString *_Nonnull)rawValue;

+ (instanceType _Nonnull)Calamari;
+ (instanceType _Nonnull)Fish;

@end

</code></pre><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// `@objc` and `String` can be applied to a struct to make it available to objective-c:
//

@objc
public struct Planets: String {
  public let rawValue: String //&lt;- This should be implicit and the user should not need to add it
  init(rawValue: String) { self.rawValue = rawValue } //&lt;- This should be implicit and the user should not need to add it

  public static let Earth = Planets(rawValue: &quot;Earth&quot;) //&lt;- user defines these
  public static let Venus = Planets(rawValue: &quot;Venus&quot;) //&lt;- user defines these
}

// This can be ported over to objective-c as a class

@interface Planets: NSObject 
- (instancetype _Nonnull)initWithRawValue:(NSString *_Nonnull)rawValue;

+ (instancetype)Earth;
+ (instancetype)Venus;
@end
</code></pre><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">The difference between a swift-enum-string and a swift-struct-string is that swift-enum-string provides a failable initializer while swift-struct-string provides a non-failable initializer.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-detailed-design" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#detailed-design" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Detailed design</h2><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-swift-string-enum---casestring-translations" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#swift-string-enum---casestring-translations" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>swift-string-enum - case/string translations</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">A swift-enum-string, is created with cases and it has an implicit string value based on the name of the case. The user may also add a name that does not equal the name of the case.</p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// Swift
@objc
public enum Food: String {
  case Calamari 
  case Fish = &quot;Flounder&quot; //&lt;-- User wants Fish to be Flounder


// Objective-c

@interface Food: NSObject

@property (readonly) NSString *_Nonnull rawValue;

+ (instanceType _Nonnull)Calamari;
+ (instanceType _Nonnull)Fish;

@end

@implementation Food
+ (instanceType _Nonnull)Calamari { return [[Food alloc] initWithRawValue:@&quot;Calimari&quot;]; }
+ (instanceType _Nonnull)Fish { return [[Food alloc] initWithRawValue:@&quot;Flounder&quot;]; } //&lt;-- Fisher contains Flounder
@end
</code></pre><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-swift-string-enum---failable-initializer" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#swift-string-enum---failable-initializer" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>swift-string-enum - failable initializer</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">A swift-enum-string has the ability to be initialized with a string. If the string matches one of the possible cases, then it returns it, otherwise it will return nil. This feature might be implemented as a dictionary or some other means that gets the same results; Below is my suggestion.</p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// Assuming this swift implementation
@objc
public enum Food: String {
  case Calamari 
  case Fish = &quot;Flounder&quot; //&lt;-- User wants Fish to be Flounder


// The objective-c failable initializer may look like this.
@implementation Food

- (instancetype _Nullable)initWithRawValue:(NSString *_Nonnull)rawValue {
  static NSDictionary &lt;NSString *, NSString *&gt;*states;
  if (!states) {
    // A dictionary where the KEYs are the acceptable rawValue&#39;s and the VALUE are empty strings
    states = @{
      @&quot;Calimari&quot; : @&quot;&quot;,
      @&quot;Flounder&quot; : @&quot;&quot;
    }
  }

  if ((self = [super init])) {
    if (states[rawValue]) {
      _rawValue = rawValue
      return self;
    }
  }
  return nil;
}

@end
</code></pre><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-swift-string-enum---methods" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#swift-string-enum---methods" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>swift-string-enum - methods</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">swift enums allow methods to be defined. If you mark a method with <code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">@objc</code> it should be made available to objective-c. </p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// Swift
@objc
public enum Food: String {
  case Calamari 
  case Fish

  @objc func price() -&gt; Double {
    // ...
  }


// Objective-c
@interface Food: NSObject 
// ...

- (Double)price;

// ...
@end
</code></pre><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-swift-struct-string---string-translations" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#swift-struct-string---string-translations" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>swift-struct-string - string translations</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">A swift-struct-string needs to be marked with <code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">@objc</code> and inherit from <code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">String</code> to bridge to objective-c. A property or method must be marked with @objc to be made available to objective-c.</p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// Swift
@objc
struct Planet {
  @objc public static let Earth = Planet(rawValue: &quot;Earth&quot;)

  @objc public func distanceFromSun() -&gt; Double { ... }
}

// Objective-c
@interface Planet
+ (instancetype _Nonnull)Earth;
+ (Double)distanceFromSun;
@end
</code></pre><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-swift-struct-string---non-failable-initializer" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#swift-struct-string---non-failable-initializer" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>swift-struct-string - non-failable initializer</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">The swift-struct-string initializer should not be failable and will accept any string value</p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">@implementation Planet
- (instancetype _Nonnull)initWithRawValue:(NSString *)rawValue {
  if ((self = [super init])) {
    _rawValue = rawValue;
  }

  return self;
}
@end
</code></pre><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-swift-struct-string---extension" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#swift-struct-string---extension" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>swift-struct-string - extension</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">One of the key attributes of an extensible string enum is that it can be extended. This should produce something available to objective-c. The original definition of Planet needs to have been marked with @objc.</p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// Swift
extension Planet {
  @objc public static let Pluto = Planet(rawValue: &quot;Pluto&quot;)
}

// Objective-c

@interface Planet (extention_1)
- (instancetype _Nonnull)Pluto;
@end

@implementation Planet (extention_1)
- (instancetype _Nonnull)Pluto {
  return [[Planet alloc] initWithRawValue:@&quot;Pluto&quot;];
}
@end
</code></pre><h3 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;font-size:1.25em;line-height:1.25;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-swift-string-enum--swift-struct-string---equalityhashrawvalue" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#swift-string-enum--swift-struct-string---equalityhashrawvalue" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>swift-string-enum &amp;&amp; swift-struct-string - equality/hash/rawValue</h3><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">When an enum or struct is marked with <code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">@objc</code> and <code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px">String</code>, the objective-c class that is produced should have its equality/hash methods and rawValue property implicitly be implemented. The user should not need to implement these on his/her own. </p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">@implementation Food

- (instancetype)rawValue { return _rawValue; }

- (NSUInteger)hash {
  return [[self rawValue] hash];
}

- (BOOL)isEqual:(id)object {
  if (self == object) { return YES }
  if (![object isKindOfClass:[Food class]]) { return NO; }

  return [self.rawValue isEqualToString:((Food *)object).rawValue];
}

@end
</code></pre><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-objective-c-name" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#objective-c-name" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Objective-c name</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">In the above examples, the objective-c name of the class and the swift name of the class were the same. If this causes a naming conflict then the objective-c name could be Prefixed with ENUM.</p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// Swift
@objc
enum Planet: String { ... }

// Objective-c
@interface ENUMPlanet
@end
</code></pre><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">The programmer should still be able to add their own name by specifying it as an argument.</p><pre style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;font-size:13.600000381469727px;margin-top:0px;margin-bottom:16px;line-height:1.45;word-wrap:normal;padding:16px;overflow:auto;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;color:rgb(51,51,51)"><code style="box-sizing:border-box;font-family:sfmono-regular,consolas,&#39;liberation mono&#39;,menlo,courier,monospace;padding:0px;margin:0px;background-color:transparent;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-break:normal;border:0px;display:inline;overflow:visible;line-height:inherit;word-wrap:normal">// Swift
@objc(CustomPlanet)
enum Planet { ... }

// Objective-c
@interface CustomPlanet
@end
</code></pre><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-source-compatibility" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#source-compatibility" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Source compatibility</h2><p style="box-sizing:border-box;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px">This will be an additive feature and will not break anything existing.</p><h2 style="box-sizing:border-box;margin-top:24px;margin-bottom:16px;line-height:1.25;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;"><a id="inbox-user-content-alternatives-considered" class="inbox-anchor" href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md#alternatives-considered" style="box-sizing:border-box;background-color:transparent;color:rgb(64,120,192);text-decoration:none;float:left;padding-right:4px;line-height:1"></a>Alternatives considered</h2><ul style="box-sizing:border-box;padding-left:2em;margin-top:0px;color:rgb(51,51,51);font-family:-apple-system,blinkmacsystemfont,&#39;segoe ui&#39;,helvetica,arial,sans-serif,&#39;apple color emoji&#39;,&#39;segoe ui emoji&#39;,&#39;segoe ui symbol&#39;;font-size:16px;margin-bottom:0px"><li style="box-sizing:border-box"><p style="box-sizing:border-box;margin-top:16px;margin-bottom:16px">Implement a swift class that implements the above described behviors.</p></li><li style="box-sizing:border-box;margin-top:0.25em"><p style="box-sizing:border-box;margin-top:16px;margin-bottom:16px">Don&#39;t change anything.</p></li></ul></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Feb 21, 2017 at 6:09 PM Derrick Ho &lt;<a href="mailto:wh1pch81n@gmail.com">wh1pch81n@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">True.  <br class="gmail_msg">In my proposal I mention how NS_STRING_ENUM  doesn&#39;t produce an swift enum.<br class="gmail_msg"><br class="gmail_msg">So one solution is to merely &quot;go the other way&quot; which would produce what Kevin N. suggested.  <br class="gmail_msg"><br class="gmail_msg">Is it not odd that that the objc version is so different from the swift version?<br class="gmail_msg"><br class="gmail_msg">Would it not be better to offer a somewhat similar API experience between the two languages?<br class="gmail_msg"><br class="gmail_msg">@objcstring would &quot;promote&quot; the swift enum to an objective-c class to make the API experience similar.<br class="gmail_msg"><br class="gmail_msg">I understand that maybe @objcstring is too niche to get its own annotation.  Instead @objc should become more powerful.<br class="gmail_msg"><br class="gmail_msg">I think @objc should make an enum become a class with swift-enum like abilities.  This would allow enum functions to be bridged over to objective-c as well.<br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Tue, Feb 21, 2017 at 1:32 PM Michael Ilseman &lt;<a href="mailto:milseman@apple.com" class="gmail_msg" target="_blank">milseman@apple.com</a>&gt; wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">A quick note addressing a misconception that you’ll want to clean up for a formal proposal:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">NS_[EXTENSIBLE_]STRING_ENUMs both generate Swift structs, the difference is only in the explicitness of the rawValue initializer. To use the “other direction” analogy, you’d similarly want them to apply for rawValue-ed structs alone. The reasons are the same: only the structs are layout-compatible because enums are integers.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Once you go down this route, perhaps it doesn’t make sense to annotate the struct decls themselves anymore. Maybe you just want more @objc control over bridging the types. For example, maybe you want to introduce a feature so that static members that are layout-compatible with String are bridged as global strings with the supplied name.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"></blockquote></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Feb 20, 2017, at 4:07 PM, Derrick Ho via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-3761581849739688303m_8141121511202417595Apple-interchange-newline gmail_msg"></blockquote></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">Swift should not forsake objective-c.  At least not when it comes enum strings.  Although swift enums are suppose to be swift only, I think we should add a new attribute to slightly relax that.  I think a good attribute would be @objcstring.</div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><br class="gmail_msg"></div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">By adding @objcstring, an objective-c exclusive class will be generated.</div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><br class="gmail_msg"></div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">@objcstring</div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">enum Planet {</div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">  case Jupiter</div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">}</div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><br class="gmail_msg"></div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">I have written up a proposal with more details on what it would look for objective-c.</div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><br class="gmail_msg"></div><a href="https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md" class="gmail_msg" style="word-spacing:1px" target="_blank">https://github.com/wh1pch81n/swift-evolution/blob/swift-enum-objc/proposals/NNNN-Swift-enum-strings-ported-to-Objective-c.md</a><br class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><br class="gmail_msg"></div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">If no one objects to this proposal I&#39;ll submit it.</div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px"><br class="gmail_msg"></div><div class="gmail_msg" style="color:rgb(49,49,49);word-spacing:1px">**notes: I am reviving this discussion so that I may submit this for Swift 4 stage 2</div></div></div></blockquote></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">
_______________________________________________<br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"></div></blockquote></div></div></blockquote></div></blockquote></div>