iOS 应用程序或 Playground 中的流程是否始终未解决?
Is Process always unresolved in iOS app or Playground?
在 iOS 应用程序中,我想使用一个文件,该文件使用 Process 具有以下功能:
public func system(_ body: String) throws {
if #available(macOS 10.0, *) {
let process = Process()
...
} else {
fatalError()
}
}
然后,即使我应用了 Availability Condition 并且我没有调用这个函数,我还是得到了一个休闲错误:
使用未解析的标识符 'Process'.
我在 Playground 中尝试了类似的代码,但我得到了同样的错误。
我了解到我们不能通过这个问题以常规方式在 iOS 应用程序中使用 Process:How to execute terminal commands in Swift 4? ,我有一个解决方案,我通过使用平台将这些代码与文件分开。但如果可以的话,我想使用这个单一文件。
请为我的理想提供另一种解决方案。
if #available()
对 OS 版本执行 运行时检查 。
if #available(macOS 10.0, *)
如果代码在 macOS 10.0 或更高版本上为 运行,则计算结果为 true
,
或 在 iOS/tvOS/watchOS 上 OS 至少是最低部署目标。
你要的是条件编译,取决于平台:
#if os(macOS)
let process = Process()
#else
// ...
#endif
即使你已经解决了这个问题,只是为了让你知道,我想告诉你实际上,Process()
(或 Swift 3.0 或更高版本中的 CommandLine()
)是可用于 iOS,但您需要使用 custom Objective-C header file 来创建对象 Process()
/CommandLine()
,或者更确切地说 NSTask()
,以及它需要的一切。
然后,为了将此代码与 Swift 一起使用,您需要创建一个 Bridging-Header,您需要在其中导入 NSTask.h
文件接触 Swift 并能够在您的 Swift 代码中使用它。
完成后,使用 NSTask()
而不是 Process()
:
let process = NSTask() /* or NSTask.init() */
或者只要您想 运行 一个任务就在您的代码中使用以下函数:
func task(launchPath: String, arguments: String...) -> NSString {
let task = NSTask.init()
task?.setLaunchPath(launchPath)
task?.arguments = arguments
// Create a Pipe and make the task
// put all the output there
let pipe = Pipe()
task?.standardOutput = pipe
// Launch the task
task?.launch()
task?.waitUntilExit()
// Get the data
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
return output!
}
如您所见,在这种情况下,NSTask()
等同于 Process()
。
并这样称呼它:
task(launchPath: "/usr/bin/echo", arguments: "Hello World")
这也将 return 值,因此您甚至可以通过以下方式显示它:
print(task(launchPath: "/usr/bin/echo", arguments: "Hello, World!"))
将打印:
~> Hello, World!
为了使其正常工作而不抛出 NSInternalInconsistencyException
,您需要将 launchPath 设置为可执行文件的完整路径,而不只是包含它的目录。
您还需要设置所有由 逗号分隔的命令参数.
在 iPad Mini 2 (iOS 12.1 ~> 越狱) 和 iPhone Xr (iOS 12.2 ~> 未越狱).
注意:即使这适用于 non-jailbroken 和越狱设备,您的应用程序将在 AppStore 上被拒绝,正如 @ClausJørgensen 所说:
You're using private APIs, so it'll be rejected on the App Store. Also, Xcode 11 has some new functionality that will trigger a build failure when using certain private APIs.
如果您的应用程序针对越狱的 iOS 设备,并且将被上传到 third-party 商店,如 Cydia、Zebra、Thunderbolt 或 Sileo,那么这将正常工作。
希望对您有所帮助。
在 iOS 应用程序中,我想使用一个文件,该文件使用 Process 具有以下功能:
public func system(_ body: String) throws {
if #available(macOS 10.0, *) {
let process = Process()
...
} else {
fatalError()
}
}
然后,即使我应用了 Availability Condition 并且我没有调用这个函数,我还是得到了一个休闲错误: 使用未解析的标识符 'Process'.
我在 Playground 中尝试了类似的代码,但我得到了同样的错误。
我了解到我们不能通过这个问题以常规方式在 iOS 应用程序中使用 Process:How to execute terminal commands in Swift 4? ,我有一个解决方案,我通过使用平台将这些代码与文件分开。但如果可以的话,我想使用这个单一文件。
请为我的理想提供另一种解决方案。
if #available()
对 OS 版本执行 运行时检查 。
if #available(macOS 10.0, *)
如果代码在 macOS 10.0 或更高版本上为 运行,则计算结果为 true
,
或 在 iOS/tvOS/watchOS 上 OS 至少是最低部署目标。
你要的是条件编译,取决于平台:
#if os(macOS)
let process = Process()
#else
// ...
#endif
即使你已经解决了这个问题,只是为了让你知道,我想告诉你实际上,Process()
(或 Swift 3.0 或更高版本中的 CommandLine()
)是可用于 iOS,但您需要使用 custom Objective-C header file 来创建对象 Process()
/CommandLine()
,或者更确切地说 NSTask()
,以及它需要的一切。
然后,为了将此代码与 Swift 一起使用,您需要创建一个 Bridging-Header,您需要在其中导入 NSTask.h
文件接触 Swift 并能够在您的 Swift 代码中使用它。
完成后,使用 NSTask()
而不是 Process()
:
let process = NSTask() /* or NSTask.init() */
或者只要您想 运行 一个任务就在您的代码中使用以下函数:
func task(launchPath: String, arguments: String...) -> NSString {
let task = NSTask.init()
task?.setLaunchPath(launchPath)
task?.arguments = arguments
// Create a Pipe and make the task
// put all the output there
let pipe = Pipe()
task?.standardOutput = pipe
// Launch the task
task?.launch()
task?.waitUntilExit()
// Get the data
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
return output!
}
如您所见,在这种情况下,NSTask()
等同于 Process()
。
并这样称呼它:
task(launchPath: "/usr/bin/echo", arguments: "Hello World")
这也将 return 值,因此您甚至可以通过以下方式显示它:
print(task(launchPath: "/usr/bin/echo", arguments: "Hello, World!"))
将打印:
~> Hello, World!
为了使其正常工作而不抛出 NSInternalInconsistencyException
,您需要将 launchPath 设置为可执行文件的完整路径,而不只是包含它的目录。
您还需要设置所有由 逗号分隔的命令参数.
在 iPad Mini 2 (iOS 12.1 ~> 越狱) 和 iPhone Xr (iOS 12.2 ~> 未越狱).
注意:即使这适用于 non-jailbroken 和越狱设备,您的应用程序将在 AppStore 上被拒绝,正如 @ClausJørgensen 所说:
You're using private APIs, so it'll be rejected on the App Store. Also, Xcode 11 has some new functionality that will trigger a build failure when using certain private APIs.
如果您的应用程序针对越狱的 iOS 设备,并且将被上传到 third-party 商店,如 Cydia、Zebra、Thunderbolt 或 Sileo,那么这将正常工作。
希望对您有所帮助。