Swift代码有没有办法检测它是否在Playground中运行?

4
为了能够测试GameKit功能,我想要检测代码是否在Playground中运行,以便它可以跳过网络调用。有没有办法做到这一点?
编辑:忘记GameKit吧,那会使问题变得复杂。有许多不同的情况下这将是有用的。这实际上只是一个简单的问题,即是否存在特定的函数调用:是否有一种方法返回true,如果代码正在Playground中运行?

代码不应该依赖于它所运行的位置,它应该只执行它的任务。也许你的代码的用户应该能够自己设置是否进行网络操作。 - Kametrixom
1
我相信我理解您所说的公理,但它有点错误陈述。所有代码都是上下文相关的。每一行代码都依赖于它运行的位置。我认为您正在处理关注点分离。也就是说,选择进行网络调用的代码应该与执行这些调用的代码分开。这是正确的、好的。我的实际问题是,“Swift代码能否检测到它是否在playground中运行?” - Le Mot Juiced
谢谢!如果你想把它作为答案,我会给你。 - Le Mot Juiced
2个回答

4
我不知道有文档记录的方法来完成此操作,但有一些未经记录的操作可以做到。
下面是一种技术,适用于Xcode 7与Swift 2.2以及Xcode 8与Swift 3.0,在macOS和iOS游乐场中都可行: 检查开始标识符为"com.apple.dt"的捆绑包。
// Swift 2.2

if NSBundle.allBundles().contains({ ($0.bundleIdentifier ?? "").hasPrefix("com.apple.dt.") }) {
    print("in playground")
} else {
    print("not in playground")
}


// Swift 3.0

if Bundle.allBundles.contains(where: { ($0.bundleIdentifier ?? "").hasPrefix("com.apple.dt.") }) {
    print("in playground")
} else {
    print("not in playground")
}

请注意,com.apple.dt.不是专门为playground相关的bundle保留的前缀;"dt" 部分代表类似于“开发工具”的东西。因此,在某些情况下可能会出现虚假阳性:存在一个匹配的bundle但你不在playground中。我不清楚任何这样的情况,但可能会有一些。我测试了一个在Xcode 7下的macOS xib中的IBDesignable视图,并没有加载任何com.apple.dt。 bundles。

在Swift Playgrounds和iOS 16.1中无法工作。 - oxygen

0
我使用包含“swift-playgrounds”的应用程序包标识更新了先前的答案。
public var inPlayground: Bool {
    if Bundle.allBundles.contains(where: { ($0.bundleIdentifier ?? "").contains("swift-playgrounds") }) {
        return true
    } else {
        return false
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接