{"id":20799,"date":"2018-03-05T15:48:56","date_gmt":"2018-03-05T20:48:56","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=20799"},"modified":"2020-04-21T13:53:38","modified_gmt":"2020-04-21T17:53:38","slug":"first-class-swift-api-for-objective-c-frameworks","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2018\/03\/05\/first-class-swift-api-for-objective-c-frameworks\/","title":{"rendered":"First-Class Swift API for Objective-C Frameworks"},"content":{"rendered":"<p><a href=\"https:\/\/pspdfkit.com\/blog\/2018\/first-class-swift-api-for-objective-c-frameworks\/\">Marcin Krzy&#x17C;anowski<\/a>:<\/p>\n<blockquote cite=\"https:\/\/pspdfkit.com\/blog\/2018\/first-class-swift-api-for-objective-c-frameworks\/\"><p>In Objective-C, it&rsquo;s possible to store a block as an <code>id<\/code> type, e.g. in a collection like <code>NSDictionary&lt;String *, id&gt;<\/code>. However, <a href=\"https:\/\/www.youtube.com\/watch?v=4F4qzPbcFiA\">that&rsquo;s a trap<\/a>. If we store a Swift closure in the imported dictionary type, it will crash at the time we access the value.<\/p><p>There is a workaround, but it has to be done on the Swift side. Declare the closure type with the <code>@convention(block)<\/code> and use it as a type[&#8230;]<\/p><p>[&#8230;]<\/p><p>The non-system framework Objective-C <code>NSUInteger<\/code> is imported as <code>UInt<\/code>. That&rsquo;s not very consistent with the Swift concept of having an <code>Int<\/code> as the ultimate integer type. The conversation about if <code>NSUInteger<\/code> should be automatically imported as an <code>Int<\/code> is <a href=\"https:\/\/forums.swift.org\/t\/proposal-seed-gathering-data-to-fix-the-nsuinteger-inconsistency\/5058\">already older than a year<\/a>, and we&rsquo;re still looking for a better solution in this area.<\/p><p>[&#8230;]<\/p><p>API Notes is a textual file with a set of metadata interpreted by Swift&rsquo;s Clang Importer without the need to rebuild the binary.<\/p><p>[&#8230;]<\/p><p><code>@_exported<\/code> will make an imported module re-exported as if the imported symbols were part of the intermediate module. The intermediate module is logically placed between two other modules, which is why it&rsquo;s called an overlay framework: It overlays the <code>@_exported<\/code> modules.<\/p><\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Marcin Krzy&#x17C;anowski: In Objective-C, it&rsquo;s possible to store a block as an id type, e.g. in a collection like NSDictionary&lt;String *, id&gt;. However, that&rsquo;s a trap. If we store a Swift closure in the imported dictionary type, it will crash at the time we access the value.There is a workaround, but it has to be [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2020-04-21T17:53:41Z","apple_news_api_id":"d1afa625-f774-48bf-82a0-eb06780de7d5","apple_news_api_modified_at":"2020-04-21T17:53:41Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/A0a-mJfd0SL-CoOsGeA3n1Q","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[],"tags":[168,31,1472,30,1529,54,71,1424,901],"class_list":["post-20799","post","type-post","status-publish","format-standard","hentry","tag-blocks","tag-ios","tag-ios-11","tag-mac","tag-macos-10-13","tag-objective-c","tag-programming","tag-pspdfkit","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/20799","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=20799"}],"version-history":[{"count":2,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/20799\/revisions"}],"predecessor-version":[{"id":28725,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/20799\/revisions\/28725"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=20799"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=20799"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=20799"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}