3

I'm writing a file to disk and I am in the process of converting my code to Swift 3, and got stuck on something. Wanted to see if someone could give me a push in the right direction.

My current code block is:

open let text: NSString
data = possibleData ?? Data()
open let fileURL: URL?
open let fileEncoding: String.Encoding?
fileprivate let data: Data!

text = NSString(bytesNoCopy: UnsafeMutableRawPointer(mutating: data.bytes.bindMemory(to: Void.self, capacity: data.count)), length: data.count, encoding: encoding.rawValue, freeWhenDone: false)!

Swift is saying that calling data.bytes is unavailable and to I need to use .unsafebytes instead. I don't grasp the way you invoke unsafe bytes (it's not as simple as switching bytes to unsafe bytes)

So I did a little research and some people have said to use a closure block like this:

data.withUnsafeMutableBytes {(bytes: UnsafeMutablePointer<UInt8>)->Void in
             //work with bytes in here
        }

My problem is, what do I put inside the closure block to get my above code working? I think I'm missing something fundamentally. I can't use bytes because it gives the same error again.

Anyone have any ideas? thanks!

NullHypothesis
  • 4,286
  • 6
  • 37
  • 79
  • Possible duplicate of ['bytes' is unavailable: use withUnsafeBytes instead](http://stackoverflow.com/questions/38979575/bytes-is-unavailable-use-withunsafebytes-instead) – Nazmul Hasan Nov 12 '16 at 17:10
  • 2
    What are you actually trying to achieve? Convert a string to data or vice versa? Write a string or data to a file? What is given and what is to be computed? – Martin R Nov 12 '16 at 17:31
  • Sorry, turns out this was part of "Swiftache" a previous developer used. I just upgraded it and i'm good now thanks! – NullHypothesis Nov 12 '16 at 22:48

1 Answers1

2

If you really need to use this pattern, assuming data was a var and not a let, you could do something like:

let text = data.withUnsafeMutableBytes { bytes in
    return NSString(bytesNoCopy: bytes, length: data.count, encoding: encoding.rawValue, freeWhenDone: false)!
}

Or, I don't know why you'd use NSString, so you could do:

let text = data.withUnsafeMutableBytes { bytes in
    return String(bytesNoCopy: bytes, length: data.count, encoding: encoding, freeWhenDone: false)!
}

Frankly, this whole pattern seems fragile (why forced cast? why using unsafe pointers rather than various safe patterns? etc.). If you're writing this to a file, so why wouldn't you just write the Data directly?

do {
    try data.write(to: fileURL)
} catch {
    print("Error: \(error.localizedDescription)")
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks, turns out this code was part of Swifache (3rd party library). I downloaded the latest. I completely missed this when posting b/c of the way the file was broken out and also b/c the previous dev removed the comments. Thanks so much though, you helped me catch that (by questioning the form of the code overall). – NullHypothesis Nov 12 '16 at 22:47