{"id":1927,"date":"2016-07-16T22:19:37","date_gmt":"2016-07-16T14:19:37","guid":{"rendered":"http:\/\/learn-house.idv.tw\/?p=1927"},"modified":"2016-07-16T22:19:37","modified_gmt":"2016-07-16T14:19:37","slug":"%e8%bd%89how-to-call-objective-c-code-from-swift-or-swift-code-from-objective-c","status":"publish","type":"post","link":"https:\/\/learn-house.idv.tw\/?p=1927","title":{"rendered":"[\u8f49]How to call Objective C code from Swift or Swift code from Objective C"},"content":{"rendered":"<h1>Using Objective-C Classes in Swift<\/h1>\n<p>** If you have an existing class that you&#8217;d like to use, perform <b>Step 2<\/b> and then skip to <b>Step 5<\/b>. (For some cases, I had to add an explicit <code>#import &lt;Foundation\/Foundation.h<\/code> to an older ObjC File) **<\/p>\n<h3>Step 1: Add Objective-C Implementation &#8212; .m<\/h3>\n<p>Add a <code>.m<\/code> file to your class, and name it <code>CustomObject.m<\/code><\/p>\n<h3>Step 2: Add Bridging Header<\/h3>\n<p>When adding your <code>.m<\/code> file, you&#8217;ll likely be hit with a prompt that looks like this:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.stack.imgur.com\/nakLZ.png\" alt=\"enter image description here\" \/><\/p>\n<p>Click <b>YES <\/b>!<\/p>\n<p>If you did not see the prompt, or accidentally deleted your bridging header, add a new <code>.h<\/code> file to your project and name it <code>&lt;#YourProjectName#&gt;-Bridging-Header.h<\/code><\/p>\n<p><!--more-->In some situations, particularly when working with ObjC frameworks, you don&#8217;t add an Objective-C class explicitly and Xcode can&#8217;t find the linker. In this case, create your <code>.h<\/code> file named as mentioned above, then make sure you link its path in your target&#8217;s project settings like so:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/i.stack.imgur.com\/8LiwF.gif\" alt=\"enter image description here\" \/><\/p>\n<p><b>Note<\/b><\/p>\n<p>It&#8217;s best practice to link your project using the <code>$(SRCROOT)<\/code> macro so that if you move your project, or work on it with others using a remote repo, it will still work. <code>$(SRCROOT)<\/code> can be thought of as the directory that contains your .xcodeproj file. It might look like this:<\/p>\n<p><code>$(SRCROOT)\/Folder\/Folder\/&lt;#YourProjectName#&gt;-Bridging-Header.h<\/code><\/p>\n<h3>Step 3: Add Objective-C Header &#8212; .h<\/h3>\n<p>Add another <code>.h<\/code> file and name it <code>CustomObject.h<\/code><\/p>\n<h3>Step 4: Build your Objective-C Class<\/h3>\n<p>In <code>CustomObject.h<\/code><\/p>\n<pre class=\"lang-c prettyprint prettyprinted\"><code><span class=\"com\">#import &lt;Foundation\/Foundation.h&gt;<\/span>\r\n\r\n<span class=\"lit\">@interface<\/span> <span class=\"typ\">CustomObject<\/span> <span class=\"pun\">:<\/span> <span class=\"typ\">NSObject<\/span>\r\n\r\n<span class=\"lit\">@property<\/span> <span class=\"pun\">(<\/span><span class=\"pln\">strong<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> nonatomic<\/span><span class=\"pun\">)<\/span><span class=\"pln\"> id someProperty<\/span><span class=\"pun\">;<\/span>\r\n\r\n<span class=\"pun\">-<\/span> <span class=\"pun\">(<\/span><span class=\"kwd\">void<\/span><span class=\"pun\">)<\/span><span class=\"pln\"> someMethod<\/span><span class=\"pun\">;<\/span>\r\n\r\n<span class=\"lit\">@end<\/span><\/code><\/pre>\n<p>In <code>CustomObject.m<\/code><\/p>\n<pre class=\"lang-c prettyprint prettyprinted\"><code><span class=\"com\">#import \"CustomObject.h\"<\/span>\r\n\r\n<span class=\"lit\">@implementation<\/span> <span class=\"typ\">CustomObject<\/span> \r\n\r\n<span class=\"pun\">-<\/span> <span class=\"pun\">(<\/span><span class=\"kwd\">void<\/span><span class=\"pun\">)<\/span><span class=\"pln\"> someMethod <\/span><span class=\"pun\">{<\/span>\r\n    <span class=\"typ\">NSLog<\/span><span class=\"pun\">(@<\/span><span class=\"str\">\"SomeMethod Ran\"<\/span><span class=\"pun\">);<\/span>\r\n<span class=\"pun\">}<\/span>\r\n\r\n<span class=\"lit\">@end<\/span><\/code><\/pre>\n<h3>Step 5: Add Class to Bridging-Header<\/h3>\n<p>In <code>YourProject-Bridging-Header.h<\/code>:<\/p>\n<pre class=\"lang-c prettyprint prettyprinted\"><code><span class=\"com\">#import \"CustomObject.h\"<\/span><\/code><\/pre>\n<h3>Step 6: Use your Object<\/h3>\n<p>In <code>SomeSwiftFile.swift<\/code>:<\/p>\n<pre class=\"lang-c prettyprint prettyprinted\"><code><span class=\"pln\">var instanceOfCustomObject<\/span><span class=\"pun\">:<\/span> <span class=\"typ\">CustomObject<\/span> <span class=\"pun\">=<\/span> <span class=\"typ\">CustomObject<\/span><span class=\"pun\">()<\/span><span class=\"pln\">\r\ninstanceOfCustomObject<\/span><span class=\"pun\">.<\/span><span class=\"pln\">someProperty <\/span><span class=\"pun\">=<\/span> <span class=\"str\">\"Hello World\"<\/span><span class=\"pln\">\r\nprintln<\/span><span class=\"pun\">(<\/span><span class=\"pln\">instanceOfCustomObject<\/span><span class=\"pun\">.<\/span><span class=\"pln\">someProperty<\/span><span class=\"pun\">)<\/span><span class=\"pln\">\r\ninstanceOfCustomObject<\/span><span class=\"pun\">.<\/span><span class=\"pln\">someMethod<\/span><span class=\"pun\">()<\/span><\/code><\/pre>\n<p>No need to import explicitly, that&#8217;s what the bridging header is for.<\/p>\n<h1>Using Swift Classes in Objective-C<\/h1>\n<h3>Step 1: Create New Swift Class<\/h3>\n<p>Add a <code>.swift<\/code> file to your project, and name it <code>MySwiftObject.swift<\/code><\/p>\n<p>In <code>MySwiftObject.swift<\/code>:<\/p>\n<pre class=\"lang-c prettyprint prettyprinted\"><code><span class=\"kwd\">import<\/span> <span class=\"typ\">Foundation<\/span>\r\n\r\n<span class=\"kwd\">class<\/span> <span class=\"typ\">MySwiftObject<\/span> <span class=\"pun\">:<\/span> <span class=\"typ\">NSObject<\/span> <span class=\"pun\">{<\/span><span class=\"pln\">\r\n\r\n    var someProperty<\/span><span class=\"pun\">:<\/span> <span class=\"typ\">AnyObject<\/span> <span class=\"pun\">=<\/span> <span class=\"str\">\"Some Initializer Val\"<\/span><span class=\"pln\">\r\n\r\n    init<\/span><span class=\"pun\">()<\/span> <span class=\"pun\">{}<\/span><span class=\"pln\">\r\n\r\n    func someFunction<\/span><span class=\"pun\">(<\/span><span class=\"pln\">someArg<\/span><span class=\"pun\">:<\/span><span class=\"typ\">AnyObject<\/span><span class=\"pun\">)<\/span> <span class=\"pun\">-&gt;<\/span> <span class=\"typ\">String<\/span> <span class=\"pun\">{<\/span><span class=\"pln\">\r\n        var returnVal <\/span><span class=\"pun\">=<\/span> <span class=\"str\">\"You sent me \\(someArg)\"<\/span>\r\n        <span class=\"kwd\">return<\/span><span class=\"pln\"> returnVal\r\n    <\/span><span class=\"pun\">}<\/span>\r\n\r\n<span class=\"pun\">}<\/span><\/code><\/pre>\n<h3>Step 2: Import Swift Files to ObjC Class<\/h3>\n<p>In <code>SomeRandomClass.m<\/code>:<\/p>\n<pre class=\"lang-c prettyprint prettyprinted\"><code><span class=\"com\">#import \"&lt;#YourProjectName#&gt;-Swift.h\"<\/span><\/code><\/pre>\n<p>The file:<code>&lt;#YourProjectName#&gt;-Swift.h<\/code> should already be created automatically in your project, even if you can not see it.<\/p>\n<h3>Step 3: Use your class<\/h3>\n<pre class=\"lang-c prettyprint prettyprinted\"><code><span class=\"typ\">MySwiftObject<\/span> <span class=\"pun\">*<\/span><span class=\"pln\"> myOb <\/span><span class=\"pun\">=<\/span> <span class=\"pun\">[<\/span><span class=\"typ\">MySwiftObject<\/span> <span class=\"kwd\">new<\/span><span class=\"pun\">];<\/span>\r\n<span class=\"typ\">NSLog<\/span><span class=\"pun\">(@<\/span><span class=\"str\">\"MyOb.someProperty: %@\"<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> myOb<\/span><span class=\"pun\">.<\/span><span class=\"pln\">someProperty<\/span><span class=\"pun\">);<\/span><span class=\"pln\">\r\nmyOb<\/span><span class=\"pun\">.<\/span><span class=\"pln\">someProperty <\/span><span class=\"pun\">=<\/span> <span class=\"pun\">@<\/span><span class=\"str\">\"Hello World\"<\/span><span class=\"pun\">;<\/span>\r\n<span class=\"typ\">NSLog<\/span><span class=\"pun\">(@<\/span><span class=\"str\">\"MyOb.someProperty: %@\"<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> myOb<\/span><span class=\"pun\">.<\/span><span class=\"pln\">someProperty<\/span><span class=\"pun\">);<\/span>\r\n<span class=\"typ\">NSString<\/span> <span class=\"pun\">*<\/span><span class=\"pln\"> retString <\/span><span class=\"pun\">=<\/span> <span class=\"pun\">[<\/span><span class=\"pln\">myOb someFunction<\/span><span class=\"pun\">:@<\/span><span class=\"str\">\"Arg\"<\/span><span class=\"pun\">];<\/span>\r\n<span class=\"typ\">NSLog<\/span><span class=\"pun\">(@<\/span><span class=\"str\">\"RetString: %@\"<\/span><span class=\"pun\">,<\/span><span class=\"pln\"> retString<\/span><span class=\"pun\">);<\/span><\/code><\/pre>\n<h2>Note:<\/h2>\n<p><b>1.<\/b> CodeCompletion wasn&#8217;t behaving as accurately as I&#8217;d like it to. On my system, running a quick build w\/ &#8220;cmd + r&#8221; seemed to help Swift find some of the Objc code and vice versa.<\/p>\n<p><b>2.<\/b> If you add <code>.swift<\/code> file to an older project and get error: <code>dyld: Library not loaded: @rpath\/libswift_stdlib_core.dylib<\/code>, try completely <a href=\"http:\/\/stackoverflow.com\/q\/24002836\/2611971\">restarting Xcode.<\/a><\/p>\n<p><b>3.<\/b> While it was originally possible to use pure Swift classes in Objective-C by using the <code>@objc<\/code>prefix, after Swift 2.0, this is no longer possible. See edit history for original explanation. If this functionality is reenabled in future Swift versions, the answer will be updated accordingly.<\/p>\n<p>&nbsp;<\/p>\n<p>Reference:http:\/\/stackoverflow.com\/questions\/24002369\/how-to-call-objective-c-code-from-swift<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using Objective-C Classes in Swift ** If you have an ex<span class=\"post-excerpt-end\">&hellip;<\/span><\/p>\n<p class=\"more-link\"><a href=\"https:\/\/learn-house.idv.tw\/?p=1927\" class=\"themebutton\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-1927","post","type-post","status-publish","format-standard","hentry","category-5"],"_links":{"self":[{"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=\/wp\/v2\/posts\/1927","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1927"}],"version-history":[{"count":0,"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=\/wp\/v2\/posts\/1927\/revisions"}],"wp:attachment":[{"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1927"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1927"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learn-house.idv.tw\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1927"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}