{"id":24754,"date":"2019-03-27T16:56:51","date_gmt":"2019-03-27T20:56:51","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=24754"},"modified":"2019-03-29T09:20:32","modified_gmt":"2019-03-29T13:20:32","slug":"swift-5-released","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2019\/03\/27\/swift-5-released\/","title":{"rendered":"Swift 5 Released"},"content":{"rendered":"<p><a href=\"https:\/\/swift.org\/blog\/swift-5-released\/\">Ted Kremenek<\/a>:<\/p>\n<blockquote cite=\"https:\/\/swift.org\/blog\/swift-5-released\/\">\n<p>Swift 5 is a major milestone in the evolution of the language. Thanks to ABI stability, the Swift runtime is now included in current and future versions of Apple&rsquo;s platform operating systems: macOS, iOS, tvOS and watchOS. Swift 5 also introduces new capabilities that are building blocks for future versions, including a reimplementation of String, enforcement of exclusive access to memory during runtime, new data types, and support for dynamically callable types.<\/p>\n<\/blockquote>\n\n<p>The <a href=\"https:\/\/forums.swift.org\/t\/withunsafebytes-data-api-confusion\/22142\">main<\/a> <a href=\"https:\/\/forums.swift.org\/t\/unsaferawbufferpointer-in-swift-5\/22165\">issue<\/a> I&rsquo;ve run into (which doesn&rsquo;t seem to be part of any of the linked evolution proposals) is that the closure for <code>Data.withUnsafeBytes()<\/code> now gives you an <code>UnsafeRawBufferPointer<\/code> instead of an <code>UnsafePointer&#x3C;UInt8&#x3E;<\/code>, which is typically what I need to pass to other APIs. It was not obvious how to fix this because the initializers for <code>UnsafePointer<\/code> didn&rsquo;t seem to apply, nor did the <code>withUnsafePointer()<\/code> free function. What I came up with was:<\/p>\n<pre>let unsafeBufferPointer = unsafeRawBufferPointer.bindMemory(to: UInt8.self)\nlet unsafePointer = unsafeBufferPointer.baseAddress!\n<\/pre>\n<p>I still don&rsquo;t understand why <code>baseAddress<\/code> is defined as an optional or when it&rsquo;s safe to force unwrap it.<\/p>\n<p id=\"swift-5-released-update-2019-03-28\">Update (2019-03-28): <a href=\"https:\/\/twitter.com\/jckarter\/status\/1111012556821266432\">Joe Groff<\/a>:<\/p>\n<blockquote cite=\"https:\/\/twitter.com\/jckarter\/status\/1111012556821266432\">\n<p><code>baseAddress<\/code> is optional so that it can hold a <code>{NULL, 0}<\/code> state for empty buffers. It is always nonnull if <code>count<\/code> &gt; 0<\/p>\n<p>An empty buffer is still a valid buffer; there are a lot of tradeoffs, but making <code>baseAddress<\/code> nullable seemed like the least bad, since many C APIs that ultimately consume these buffers also accept <code>NULL<\/code> with a zero count.<\/p>\n<p>For the <code>Data<\/code> API, the count matches the <code>Data<\/code>&rsquo;s count.<\/p>\n<\/blockquote>\n<p>My takeway from this is that the <code>Data<\/code> API cannot be relied on to get you a <code>UnsafePointer&#x3C;UInt8&#x3E;<\/code> to pass to C because <code>baseAddress<\/code> could be <code>nil<\/code> if the <code>Data<\/code> is empty. This was never the case in my testing, but the API allows it, so force unwrapping is not a good idea.<\/p>\n<p>I ended up writing an extension to provide a reliable <code>UnsafePointer&#x3C;UInt8&#x3E;<\/code>:<\/p>\n<pre>func mjtWithUnsafePointer&#x3C;ResultType&#x3E;(_ body: (UnsafePointer&#x3C;UInt8&#x3E;) throws -&#x3E; ResultType) rethrows -&#x3E; ResultType {\n    return try withUnsafeBytes { (rawBufferPointer: UnsafeRawBufferPointer) -&#x3E; ResultType in\n        let unsafeBufferPointer = rawBufferPointer.bindMemory(to: UInt8.self)\n        guard let unsafePointer = unsafeBufferPointer.baseAddress else {\n            var int: UInt8 = 0\n            return try body(&#x26;int)\n        }\n        return try body(unsafePointer)\n    }\n}<\/pre>\n<p>even though the callee likely won&rsquo;t actually access it given that the size is zero.<\/p>\n<p id=\"swift-5-released-update-2019-03-29\">Update (2019-03-29): I should also note that the automatic Swift 5 conversion failed and then beachballed for all my projects. It was easy enough to update them manually, though.<\/p>","protected":false},"excerpt":{"rendered":"<p>Ted Kremenek: Swift 5 is a major milestone in the evolution of the language. Thanks to ABI stability, the Swift runtime is now included in current and future versions of Apple&rsquo;s platform operating systems: macOS, iOS, tvOS and watchOS. Swift 5 also introduces new capabilities that are building blocks for future versions, including a reimplementation [&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":"2019-03-27T20:56:53Z","apple_news_api_id":"6a64d02a-75c0-44cc-9b03-e5202d0820ed","apple_news_api_modified_at":"2019-03-29T13:20:36Z","apple_news_api_revision":"AAAAAAAAAAAAAAAAAAAAAQ==","apple_news_api_share_url":"https:\/\/apple.news\/AamTQKnXARMybA-UgLQgg7Q","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":[31,1610,30,1609,71,901],"class_list":["post-24754","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-ios","tag-ios-12","tag-mac","tag-macos-10-14","tag-programming","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/24754","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=24754"}],"version-history":[{"count":3,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/24754\/revisions"}],"predecessor-version":[{"id":24774,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/24754\/revisions\/24774"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=24754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=24754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=24754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}