{"id":980,"date":"2014-11-26T16:55:43","date_gmt":"2014-11-26T22:55:43","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=980"},"modified":"2020-05-14T17:51:01","modified_gmt":"2020-05-14T22:51:01","slug":"using-swift-in-an-existing-objective-c-project","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/using-swift-in-an-existing-objective-c-project\/","title":{"rendered":"Using Swift in an Existing Objective-C Project"},"content":{"rendered":"<p>It&#8217;s clear from the Swift tutorials out there (including ours), that folks ask the question &#8220;How do I include Objective-C frameworks in my Swift project?&#8221; more often than &#8220;How do I include Swift code in my Objective-C project?&#8221;  That&#8217;s understandable.  Swift is new and shiny and we <i>want<\/i> to start off playing with Swift first and then mix in some Objective-C when we have to (which if you are using popular frameworks such as AFNetworking, Parse, etc., you have to quickly).<\/p>\n<p>Since there&#8217;s plenty of Objective-C bridging header tutorials out there already, I thought I&#8217;d share my experience with the reverse direction:  adding Swift code to an existing Objective-C project.  I&#8217;d love to say it was easy and painless, but the reality is it was a pain in the ass (read <a href=\"http:\/\/stackoverflow.com\/questions\/24062618\/swift-to-objective-c-header-not-created-in-xcode-6\">this Stackoverflow thread<\/a> to see why!).<\/p>\n<p>Let&#8217;s start off the basic rule:  Don&#8217;t add any Swift files to your project without reading this first.  If you have already added Swift files and are scratching your head why things won&#8217;t work (namely that your <code>-Swift.h<\/code> can&#8217;t be found), delete them from your project and just start over and follow these steps:<\/p>\n<h2>Update Your Project Build Settings<\/h2>\n<p>Your <i>project&#8217;s<\/i> (not the target) build settings need to have the flag <b>Defines Module<\/b> set to YES.  Go to your project build settings page and type <b>Packaging<\/b> in the search field and then set <b>Defines Module<\/b> to YES.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/Screenshot-2014-11-26-16.04.46.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/Screenshot-2014-11-26-16.04.46.png\" alt=\"Screenshot 2014-11-26 16.04.46\" width=\"882\" height=\"229\" class=\"alignnone size-full wp-image-981\" \/><\/a><\/p>\n<h2>Make Note of Your Product Module Name<\/h2>\n<p>Did you even know you had a product module name?  I didn&#8217;t.  To find it go to your <i>target&#8217;s<\/i> (not the project) build settings and again search for Packaging.  Make note of the <b>Product Module Name<\/b>.  In our case it is <code>testing<\/code>.<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/Screenshot-2014-11-26-16.10.33.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/Screenshot-2014-11-26-16.10.33.png\" alt=\"Screenshot 2014-11-26 16.10.33\" width=\"416\" height=\"56\" class=\"alignnone size-full wp-image-982\" \/><\/a><\/p>\n<h2>Create Your Swift File<\/h2>\n<p>Create your Swift file with Xcode <b>File &#8211; New &#8211; File<\/b>.  If Xcode asks whether or not you want to create a bridging header, you can if you like, but it&#8217;s not strictly required for what we&#8217;re trying to accomplish (Swift in Objective-C not the other way around, which is what the bridging header is for).<\/p>\n<h2>The Rules<\/h2>\n<p>There are rules around what&#8217;s required to get Swift objects living in harmony in your Objective-C code.  For a complete overview see <a href=\"https:\/\/developer.apple.com\/library\/ios\/documentation\/swift\/conceptual\/buildingcocoaapps\/MixandMatch.html\">Apple&#8217;s documentation<\/a>, but here&#8217;s what I&#8217;ve found to be true:<\/p>\n<ul>\n<li>You have to <code>#import &lt;productModuleName-Swift.h&gt;<\/code> in every Objective-C class you plan to use your Swift classes in\n<li>The <code>@objc<\/code> declaration on a Swift class isn&#8217;t good enough &#8211; inherit from <code>NSObject<\/code>\n<\/ul>\n<h3>The Header File<\/h3>\n<p>What others have pointed out in the Stackoverflow post referenced early is that <b>unlike<\/b> the the Objective-C bridging header the <i>Swift bridging header<\/i> is not a file you can see in your project, but is automatically generated in the build chain.  That is, the compiler creates it as a temporary file prior to compiling your Objective-C.  Even still, you have to <code>#import<\/code> it and if Xcode complains that it isn&#8217;t available you either don&#8217;t have <b>Defines Module<\/b> set to YES, or you named the header incorrectly (it is <code>productModuleName-Swift.h<\/code>, where <code>productModuleName<\/code> is <i>your<\/i> product module name), <b>or<\/b> (and here&#8217;s the irritating part) you added a Swift file to your project <i>prior<\/i> to setting <b>Defines Module<\/b> to YES.<\/p>\n<h3>The Swift Class Definition<\/h3>\n<p>Trying to use only <code>@objc<\/code> as an indicator that you&#8217;re going to use the Swift class in Objective-C code results in ARC complaints about <code>alloc<\/code> not being defined.  Here&#8217;s a screenshot of declaring our Swift class like this:<\/p>\n<pre class=\"lang:swift decode:true \" >\nimport Foundation\n\n@objc class SwiftClass {\n  \n  init() {\n    println(\"SwiftClass init\")\n  }\n\n}<\/pre>\n<p>Unfortunately we cannot compile due to the annoying <code>No known class method for selector 'alloc'<\/code> error:<\/p>\n<p><a href=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/Screenshot-2014-11-26-16.26.26.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/Screenshot-2014-11-26-16.26.26.png\" alt=\"Screenshot 2014-11-26 16.26.26\" width=\"775\" height=\"53\" class=\"alignnone size-full wp-image-983\" \/><\/a><\/p>\n<p>Changing our class to:<\/p>\n<pre class=\"lang:swift decode:true \" >\nimport Foundation\n\nclass SwiftClass : NSObject {\n  \n  override init() {\n    super.init()\n    println(\"SwiftClass init\")\n  }\n\n}\n<\/pre>\n<p>and the compilation proceeds and we can access our Swift class.<\/p>\n<p>From there things proceeded relatively well.  Our final test included the following Swift code:<\/p>\n<pre class=\"lang:swift decode:true \" >\nimport Foundation\n\nclass SwiftClass : NSObject {\n  \n  override init() {\n    super.init()\n    println(\"SwiftClass init\")\n  }\n  \n  func sayHello() -> Void {\n    println(\"hello\");\n  }\n  \n  func addX(x:Int, andY y:Int) -> Int {\n    return x+y\n  }\n  \n  \/\/ Make a dictionary\n  \/\/ No, this code doesn't protect against values.count > keys.count\n  func dictionaryWithKeys(keys:[String], andValues values:[String]) -> Dictionary<String,String> {\n    \n    var dictionary = Dictionary<String,String>()\n    \n    for var i = 0; i < keys.count; i++ {\n      dictionary[keys[i]] = values[i]\n    }\n    \n    return dictionary\n    \n  }\n  \n}\n<\/pre>\n<p>with our delegate header including<\/p>\n<pre class=\"lang:swift decode:true \" >\n#import <testing-Swift.h>\n<\/pre>\n<p>and using it in our Objective-C application delegate:<\/p>\n<pre class=\"lang:swift decode:true \" >\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n  \n  SwiftClass* mySwiftClass = [[SwiftClass alloc]init];\n  \n  [mySwiftClass sayHello];\n  \n  int result = [mySwiftClass addX:5 andY:5];\n  \n  NSLog(@\"5 + 5 is %d\", result);\n  \n  NSDictionary* dictionary = [mySwiftClass dictionaryWithKeys:@[@\"key1\",@\"key2\",@\"key3\"] andValues:@[@\"val1\",@\"val2\",@\"val3\"]];\n  \n  NSLog(@\"dictionary = %@\", dictionary);\n  \n  return YES;\n}\n<\/pre>\n<p>As expected, our output:<\/p>\n<pre>\nSwiftClass init\nhello\n2014-11-26 16:43:28.900 testing[6536:1258140] 5 + 5 is 10\n2014-11-26 16:43:28.928 testing[6536:1258140] dictionary = {\n    key1 = val1;\n    key2 = val2;\n    key3 = val3;\n}\n<\/pre>\n<h2>Conclusion<\/h2>\n<p>If you can't get Swift classes mixed into your Objective-C code on your first attempt, you're aren't an idiot.  Future versions of Xcode one would hope will fix the annoying feature of failing to generate a <code>-Swift.h<\/code> header file if you didn't do things in exactly the right order.  In the meantime, follow these steps and definitely pore back over the <a href=\"http:\/\/stackoverflow.com\/questions\/24062618\/swift-to-objective-c-header-not-created-in-xcode-6\">Stackoverflow<\/a> thread in case you missed something.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s clear from the Swift tutorials out there (including ours), that folks ask the question &#8220;How do I include Objective-C frameworks in my Swift project?&#8221; more often than &#8220;How do I include Swift code in my Objective-C project?&#8221; That&#8217;s understandable. Swift is new and shiny and we want to start off playing with Swift first [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,5,2],"tags":[],"class_list":["post-980","post","type-post","status-publish","format-standard","hentry","category-apple","category-swift","category-xcodetips"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/980"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=980"}],"version-history":[{"count":13,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/980\/revisions"}],"predecessor-version":[{"id":1124,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/980\/revisions\/1124"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=980"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=980"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=980"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}