如何在swift中导入<sys/utsname.h>

Fun*_*nny 5 objective-c swift

我正在Swift中创建一个项目.我想显示modelName.我按照以下链接获取modelName

http://myiosdevelopment.blogspot.co.uk/2012/11/getting-device-model-number-whether-its.html
Run Code Online (Sandbox Code Playgroud)

链接中的代码用objective-c编写.但我不知道如何在Swift中导入它.

#import <sys/utsname.h>
Run Code Online (Sandbox Code Playgroud)

请有人帮忙

jou*_*jou 12

sys/utsname.h默认情况下导入Swift,因此您不需要从桥接头导入它.但是使用utsnameSwift确实很痛苦,因为Swift将固定长度的C数组导入为元组.如果你研究一下utsname.h,你会看到C struct成员utsname都是char256长度的数组:

#define _SYS_NAMELEN    256

struct  utsname {
    char    sysname[_SYS_NAMELEN];  /* [XSI] Name of OS */
    char    nodename[_SYS_NAMELEN]; /* [XSI] Name of this network node */
    char    release[_SYS_NAMELEN];  /* [XSI] Release level */
    char    version[_SYS_NAMELEN];  /* [XSI] Version level */
    char    machine[_SYS_NAMELEN];  /* [XSI] Hardware type */
};
Run Code Online (Sandbox Code Playgroud)

哪个导入Swift像这样:

var _SYS_NAMELEN: Int32 { get }

struct utsname {
    var sysname: (Int8, Int8, /* ... 254 more times "Int8, " here ... */) /* [XSI] Name of OS */
    var nodename: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Name of this network node */
    var release: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Release level */
    var version: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Version level */
    var machine: (Int8, Int8, /* ... snip ... */ ) /* [XSI] Hardware type */
}
Run Code Online (Sandbox Code Playgroud)

是的,它们是256 Int8s的元组.在Xcode中这个热闹的自动完成的案例:

Xcode完成<code> utsname </ code>初始化程序

目前,无法在不写出所有值的情况下初始化Swift中的元组,因此将其初始化为局部变量将相当冗长,如上所示.也没有办法将元组转换为数组,因此巨大的元组也不是很有用.

最简单的解决方案是在Objective-C中实现它.

如果你已经开始使用Swift,你可以这样做,但它并不漂亮:

// Declare an array that can hold the bytes required to store `utsname`, initilized
// with zeros. We do this to get a chunk of memory that is freed upon return of
// the method
var sysInfo: [CChar] = Array(count: sizeof(utsname), repeatedValue: 0)

// We need to get to the underlying memory of the array:
let machine = sysInfo.withUnsafeMutableBufferPointer { (inout ptr: UnsafeMutableBufferPointer<CChar>) -> String in
    // Call uname and let it write into the memory Swift allocated for the array
    uname(UnsafeMutablePointer<utsname>(ptr.baseAddress))

    // Now here is the ugly part: `machine` is the 5th member of `utsname` and
    // each member member is `_SYS_NAMELEN` sized. We skip the the first 4 members
    // of the struct which will land us at the memory address of the `machine`
    // member
    let machinePtr = advance(ptr.baseAddress, Int(_SYS_NAMELEN * 4))

    // Create a Swift string from the C string
    return String.fromCString(machinePtr)!
}
Run Code Online (Sandbox Code Playgroud)


Ant*_*nio 0

该博客文章中显示的代码看起来像 C 而不是 Objective C - 但我认为你可以用 Objective-C 编写一个包装器

为了启用 Objective-C 和 swift 之间的桥接,只需将一个新的 Objective-C 文件添加到您的项目中 - Xcode 将提示您是否创建桥接标头

在此输入图像描述

只要回答 yes,Xcode 就会自动创建一个<appname>-Bridging-Header.h文件。打开它以及#include您想要从 swift 使用的任何 Objective-C 头文件。