{"id":27881,"date":"2020-01-16T20:34:37","date_gmt":"2020-01-17T01:34:37","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=27881"},"modified":"2020-01-24T15:25:37","modified_gmt":"2020-01-24T20:25:37","slug":"optionals-in-swift-objective-c-interoperability","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2020\/01\/16\/optionals-in-swift-objective-c-interoperability\/","title":{"rendered":"Optionals in Swift Objective-C Interoperability"},"content":{"rendered":"<p><a href=\"https:\/\/fabiancanas.com\/blog\/2020\/1\/9\/swift-undefined-behavior.html\">Fabi&aacute;n Ca&ntilde;as<\/a> (<a href=\"https:\/\/twitter.com\/fcanas\/status\/1215352421263839239\">tweet<\/a>):<\/p>\n<blockquote cite=\"https:\/\/fabiancanas.com\/blog\/2020\/1\/9\/swift-undefined-behavior.html\"><p>The problem is that since Swift doesn&rsquo;t think this value can be nil, it&rsquo;s not trivial to check.<\/p>\n<p>[&#8230;]<\/p>\n<p>It says the non-optional value shouldn&rsquo;t be compared to nil, and that it&rsquo;s always false. But at run time, the nil is detected, and we print the statement.<\/p>\n<p>[&#8230;]<\/p>\n<p>What&rsquo;s interesting here is that the argument to the bridge function is an <code>Optional&lt;NSCalendar&gt;<\/code>. The static method, by its signature, accepts nil. What&rsquo;s happening then? In this case, The culprit for the crash and what saves us from unexpected behavior later on is a force unwrap. Though the value that&rsquo;s actually passed in to the function is <code>Optional&lt;NSCalendar&gt;.some(nil)<\/code>, which is still not a valid value and we&rsquo;re still in undefined behavior territory, so it&rsquo;s pleasantly surprising that a force unwrap catches this case.<\/p>\n<p>[&#8230;]<\/p>\n<p>Having the the compiler automatically check and assert that nonnull Objective-C types returned by Objective-C methods are indeed present would be fantastic, whether for debug builds or as an independent flag. <\/p><\/blockquote>\n\n<p><a href=\"https:\/\/twitter.com\/brentdax\/status\/1215511408776896513\">Brent Royal-Gordon<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/brentdax\/status\/1215511408776896513\">\n<p>To make sure we&rsquo;re all on the same page: returning <code>null<\/code> from a <code>nonnull<\/code> imported API is full-on, demons-flying-out-of-your-nose undefined behavior. There&rsquo;s no guarantee that it will do what you saw.<\/p>\n<\/blockquote>\n\n<p>Unfortunately, it&rsquo;s rather easy to get the annotations wrong, and even Apple does this. For example, the <code>SecDigestTransformCreate()<\/code> and <code>SecTransformExecute()<\/code> calls can return <code>NULL<\/code> in Objective-C, but Swift acts as if they can&rsquo;t fail. I filed a bug about about this, which Apple recently said was so old that they wanted to close it and have me open a new one. Meanwhile, I&rsquo;m able the work around the issue because these two APIs have a separate error pointer that can be examined. Without that, I think you would need an Objective-C wrapper to safely detect whether an error has occurred.<\/p>\n\n<p id=\"optionals-in-swift-objective-c-interoperability-update-2020-01-24\">Update (2020-01-24): <a href=\"https:\/\/forums.developer.apple.com\/thread\/127739\">Quinn the Eskimo<\/a> (via <a href=\"https:\/\/twitter.com\/dilorias\/status\/1218159192026107904\">Thomas Clement<\/a>):<\/p>\n<blockquote cite=\"https:\/\/forums.developer.apple.com\/thread\/127739\"><p>The SecTransform API is effectively deprecated, and has been so since 10.12.  Unfortunately it&rsquo;s taken a while for us to <em>formally<\/em> deprecate it (r. 25183002).<\/p><\/blockquote>","protected":false},"excerpt":{"rendered":"<p>Fabi&aacute;n Ca&ntilde;as (tweet): The problem is that since Swift doesn&rsquo;t think this value can be nil, it&rsquo;s not trivial to check. [&#8230;] It says the non-optional value shouldn&rsquo;t be compared to nil, and that it&rsquo;s always false. But at run time, the nil is detected, and we print the statement. [&#8230;] What&rsquo;s interesting here is [&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-01-17T01:34:40Z","apple_news_api_id":"95ecb5f9-471f-4e4c-b3db-871bd92eadde","apple_news_api_modified_at":"2020-01-24T20:25:40Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAA==","apple_news_api_share_url":"https:\/\/apple.news\/Aley1-UcfTkyz24cb2S6t3g","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":[4],"tags":[131,31,1667,30,1666,54,71,901],"class_list":["post-27881","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-bug","tag-ios","tag-ios-13","tag-mac","tag-macos-10-15","tag-objective-c","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/27881","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=27881"}],"version-history":[{"count":2,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/27881\/revisions"}],"predecessor-version":[{"id":27940,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/27881\/revisions\/27940"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=27881"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=27881"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=27881"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}