Chris
Chris

Reputation: 1437

How to convert cString into String in Swift6?

The following code produces a warning in Swift6:

'init(cString:)' is deprecated: Use String(decoding: array, as: UTF8.self) instead, after truncating the null termination.

  var size = 0
  sysctlbyname("hw.model", nil, &size, nil, 0)
  
  var modelIdentifier: [CChar] = Array(repeating: 0, count: size)
  sysctlbyname("hw.model", &modelIdentifier, &size, nil, 0)
  
  return String(cString: modelIdentifier)

Writing:

  return String(decoding: modelIdentifier, as: UTF8.self)

produces an error:

Type of expression is ambiguous without a type annotation

How do I get rid of this ?

Upvotes: 1

Views: 57

Answers (1)

Itai Ferber
Itai Ferber

Reputation: 29918

Writing:

return String(decoding: modelIdentifier, as: UTF8.self)

produces an error:

Type of expression is ambiguous without a type annotation

Unfortunately, this is because the type of String(decoding:as:) is

init<C, Encoding>(
    decoding codeUnits: C,
    as sourceEncoding: Encoding.Type
) where C : Collection, Encoding : _UnicodeEncoding, C.Element == Encoding.CodeUnit

i.e., codeUnits needs to be a collection of UTF8.CodeUnit, and UTF8.CodeUnit is UInt8, not CChar.

Instead, you can use String(utf8String:), which takes a [CChar] directly:

var modelIdentifier: [CChar] = Array(repeating: 0, count: size)
sysctlbyname("hw.model", &modelIdentifier, &size, nil, 0)

guard let identifier = String(utf8String: modelIdentifier) else {
    // Handle this in some appropriate fashion
    fatalError("Invalid model identifier")
}

return identifier

Upvotes: 3

Related Questions