在macOS上解码后,在iOS上编码为Data的Int数为nil

时间:2019-08-24 12:22:04

标签: ios swift macos swift4

我有这个Int数字,必须通过网络传输。

我正在使用此类扩展名。

extension Data {

  init<T>(from value: T) {
    self = Swift.withUnsafeBytes(of: value) { Data($0) }
  }

  func to<T>(type: T.Type) -> T? where T: ExpressibleByIntegerLiteral {
    var value: T = 0
    guard count >= MemoryLayout.size(ofValue: value) else { return nil }
    _ = Swift.withUnsafeMutableBytes(of: &value, { copyBytes(to: $0)} )
    return value
  }
}

我使用iOS设备上的代码对此进行编码和发送:

  let number = button.number
  let buttonNumberData = Data(from:number)

  do {
    try session.send(buttonNumberData, toPeers: session.connectedPeers, with: .reliable)
  } catch let error as NSError {
  }
}

如果我这次做po buttonNumberData,我会得到:

▿ 4 bytes
  - count : 4
  ▿ pointer : 0x002e9940
    - pointerValue : 3053888
  ▿ bytes : 4 elements
    - 0 : 1
    - 1 : 0
    - 2 : 0
    - 3 : 0

如果我以此解码数据,

let buttonNumber = buttonNumberData.to(type: Int.self)

我有一个有效的电话号码。

然后,此Data被传输并到达macOS计算机,并使用相同的命令进行解码:

let buttonNumber = buttonNumberData.to(type: Int.self)

问题在于buttonNumber始终为nil,但如果我此时进行po buttonNumberData,我将得到以下提示:

▿ 4 bytes
  - count : 4
  ▿ pointer : 0x00007ffeefbfd428
    - pointerValue : 140732920747048
  ▿ bytes : 4 elements
    - 0 : 1
    - 1 : 0
    - 2 : 0
    - 3 : 0

似乎是有效数据。

Data扩展类上出现了一些与macOS的工作有关的问题。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

Int是Swift中与平台相关的类型,可以是32位或64位整数。

显然,您是在32位设备上对整数进行编码,然后在64位设备上对其进行解码。如果数据量小于整数大小,则解码方法返回nil

使用Int32(或Int64)而不是Int来表示4(或8)字节的整数类型,而与平台无关。在所有(当前)iOS和macOS设备上都可以使用此功能,因为它们都使用相同的(小尾数)字节顺序。

对于完全独立于平台的表示,请将数据转换为定义良好的字节顺序,如here所示。