1

I'm a complete Swift newbie, but I'm writing an app for BLE using swift and have run into an issue. I'm working off of some open source code that I found in order to understand how to structure an iOS app and communicate with BLE, and when I converted it to Swift 3, a number of errors came up.

Code:

func int8Value() -> Int8 {
   var value: Int8 = 0
   copyBytes(to: &UInt8(value), count: MemoryLayout<Int8>.size)
   return value
}

Error:

Cannot pass immutable value as inout argument: function call returns immutable value

I've been looking online for solutions to this and have found the following:

I tried to implement these, taking a look at the following lines of code:

if let data = characteristic.value {
   var bytes = Array(repeating: 0 as UInt8,count:someData.count/MemoryLayout<UInt8>.size)
   data.copyBytes(to: &bytes, count:data.count)
}

and

let data = "foo".data(using: .utf8)!
let array = [UInt8](data)
let array = data.withUnsafeBytes {
    [UInt8](UnsafeBufferPointer(start: $0, count: data.count))
}

I don't really understand the correlation between the them other than a few common variables. Can someone explain what is happening inside of the CopyBytes function (what "to" and "count" are doing), what the error is coming from, and if the examples I've been looking at have anything to do with the method I'm trying to fix?

Community
  • 1
  • 1
zmillard
  • 115
  • 9
  • @Martin R I'm confused why you marked my question as a duplicate when the other was asked a month after mine was....? – zmillard Aug 11 '17 at 17:23
  • 1
    The temporal ordering of duplicates is not relevant. Users typically choose the question with the best answers as the "master" question. There is no penalty for having your question marked as a duplicate, so this is not really something to worry about. – Cody Gray - on strike Aug 11 '17 at 17:43
  • Ooh okay got it, thank you @CodyGray – zmillard Aug 11 '17 at 17:43

1 Answers1

1

It looks like there was an issue with the type casting from Int8 to UInt8, and taking the address of the resulting UInt8 conversion. The result of the cast is an immutable value, whose memory location cannot be passed as the function argument. If you simply initialize the variable as an unsigned int, it should pass the address just fine.

The following code should work:

func int8Value() -> Int8 {
    var value: UInt8 = 0
    copyBytes(to: &value, count: MemoryLayout<Int8>.size)
    return Int8(value)
}
Jonathan H.
  • 939
  • 1
  • 7
  • 21
  • Note that `Int8(value)` crashes at runtime if `value` is outside of the range 0...127. Compare http://stackoverflow.com/a/41653097/1187415. – Martin R Jan 14 '17 at 18:22