6 Replies
      Latest reply: Nov 17, 2016 4:11 AM by eskimo RSS
      zach.m Level 1 Level 1 (0 points)

        I had Xcode 8 convert my code to Swift 3.  It changed all occruances of NSData to Data. In my Swift 2 code I had:

         

        var data : NSData

        var bytes = data.bytes

         

        In Swift 3 I believe that I should be using withUnsafeMutbaleBytes and my code should looks somehting like:

         

        var data : Data

        var bytes = data.withUnsafeMutableBytes { (<#UnsafeMutablePointer<ContentType>#>) -> ResultType in

                    <#code#>

                }

         

        There isn't much documentation yet and I can't figure out how to properly use withUnsafeMutableBytes. Are there any examples of how to use withUnsafeMutableBytes?

        • Re: Data withUnsafeMutableBytes
          OOPer Level 7 Level 7 (3,325 points)

          Basic usage of `withUnsafeBytes` and `withUnsafeMutableBytes`.

           

          import UIKit
          var str = "Hello, playground"
          let data1 = str.data(using: String.Encoding.utf8)!
          data1.withUnsafeBytes {(bytes: UnsafePointer<CChar>)->Void in
              //Use `bytes` inside this closure
              //...
          }
          var data2 = Data(capacity: 1024)!
          data2.withUnsafeMutableBytes {(bytes: UnsafeMutablePointer<UInt8>)->Void in
              //Use `bytes` inside this closure
              //...
          }
          

           

          If you want to work with beta software, you need to work with incomplete documetation and no example codes.

          You need to "infer" the usage from other similar name methods.

            • Re: How to use Data withUnsafeMutableBytes in Swift 3
              zach.m Level 1 Level 1 (0 points)

              Thanks!  I've developed macOS and iOS code for close to 20 years and used a lot of beta software with and without documentaiton, but I was having difficulty with this syntax in Swift. Thanks again.

              • Re: How to use Data withUnsafeMutableBytes in Swift 3
                intrepid-paul Level 1 Level 1 (0 points)

                Just want to point out that `withUnsafeBytes` is a throwing function and actually needs a `try` in front of it. But this was very helpful for me. Thanks!

                let transmission = packet.contents
                try transmission.withUnsafeBytes { (unsafePointer: UnsafePointer<UInt8>) in
                    let written = write(unsafePointer, maxLength: transmission.count)
                           
                    if written != transmission.count {
                        throw Error.unableToWriteAllBytes
                    }
                }
                
                  • Re: How to use Data withUnsafeMutableBytes in Swift 3
                    eskimo Apple Staff Apple Staff (5,995 points)

                    Just want to point out that withUnsafeBytes is a throwing function and actually needs a try in front of it.

                    Just FYI, it’s actually a rethrow function, which means that it throws if the block you pass it throws.  Which is pretty cool.  You can learn more in the Rethrowing Functions and Methods section of The Swift Programming Language

                    Share and Enjoy

                    Quinn “The Eskimo!”
                    Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                    let myEmail = "eskimo" + "1" + "@apple.com"

                • Re: How to use Data withUnsafeMutableBytes in Swift 3
                  rsharp Level 3 Level 3 (135 points)

                  I used to do much more work with the withUnsafeMutablesBytes API myself.  But after converting to Swift 3 and fully embracing the new Data type, I've not found much need for it.

                   

                  What specifically are you needing to do? You may find that directly reading/writing/comparing as follows may be sufficient:

                   

                  var theData = Data(bytes: [0x01, 0x02, 0x03])
                  let theValue = theData[2]     // 0x02
                  theData[2] = 0xFF
                  let theNewValue = theData[2]  // 0xFF
                  
                  let theIsEqualFlag = (theData == Data(bytes: [0x01, 0x02, 0xFF])) // true