向 info.plist 添加了自定义键,当我从 Swift 的游乐场访问时,它是 nil

Posted

技术标签:

【中文标题】向 info.plist 添加了自定义键,当我从 Swift 的游乐场访问时,它是 nil【英文标题】:added custom key to info.plist, when I access from playground in Swift, it is nil 【发布时间】:2016-01-02 03:18:24 【问题描述】:

使用 Xcode 7.2(在 Yosemite 上),我似乎无法从操场上的 info.plist 访问自定义密钥:

import UIKit
var str = "Hello, playground"
let app_id = NSBundle.mainBundle().infoDictionary?["MyAppID"] as? String

使用上面的代码,app_id 为 nil。我希望它是字符串“TEST”

我将它包含在我的 info.plist 中,如下所示:

游乐场有一些我没有读过的限制吗?

如果我打印所有键,我的自定义键丢失:

let dict = NSBundle.mainBundle().infoDictionary!
for k in dict.keys 
  print("\(k)")

打印以下内容:

DTSDKName
CFBundleIdentifier
CFBundleSupportedPlatforms
CFBundleInfoDictionaryVersion
LSRequiresIPhoneOS
CFBundleNumericVersion
DTPlatformName
CFBundleShortVersionString
CFBundleVersion
UIViewControllerBasedStatusBarAppearance
UIRequiredDeviceCapabilities
UIStatusBarHidden
CFBundlePackageType
UIDeviceFamily
CFBundleExecutable
CFBundleInfoPlistURL
LSBackgroundOnly
CFBundleName
CFBundleDevelopmentRegion

如果我查看 Bundle 名称,如下所示:

let name = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleName") as? String

我看到的是游乐场的名称,而不是工作区的名称。我可以访问该项目的 info.plist 吗?

【问题讨论】:

记录整个信息字典。我怀疑它是否正在查看您项目的 Info.plist。 我正在打印密钥。查看名称,@maddy 是正确的,我根本没有加载 info.plist。但是怎么做呢? 【参考方案1】:

游乐场没有Info.plist 文件。游乐场是独立的。将它们添加到项目不会导致它们访问项目中的文件。他们只能访问自己包中的文件。

您可以将 plist 文件作为资源添加到 Playground 并以这种方式读取(使用 pathForResourceNSDictionary(contentsOfFile:),但您不能在其上使用 objectForInfoDictionaryKey。您不能将其命名为“Info .plist”,因为这将与自动生成的 Info.plist 游乐场用于运行相冲突。

例如,如果您将 plist 复制到资源文件夹中,请将其命名为 MyInfo.plist,然后加载它:

let infoPath = NSBundle.mainBundle().pathForResource("MyInfo.plist", ofType: nil)!
let info = NSDictionary(contentsOfFile: infoPath)!

这与真正的 Info.plist 并不完全相同,因为不会扩展诸如 $(EXECUTABLE_NAME) 之类的内容。

但这里的要点是,playgrounds 在它们自己的包中,与应用程序无关,它们在运行时动态创建自己的 Info.plist。您在此处尝试执行的操作与 Playground 当前的工作方式不符。

理解所有这些的一个关键部分是 Playground 是真正的应用程序。它们被编译并构建为带有自己的包的可执行文件,该包安装在构建目录中。检查NSBundle.mainBundle().bundlePath 看看在哪里。当 Playground 运行时,它不知道它的源代码来自哪里,更不用说它可能位于某个更大的目录结构中了。即使是 __FILE__ 宏也被丢弃(它返回 <EXPR>)。

我希望他们将来会对此进行改进,因为目前有很多类似的事情使他们难以用于探索现有的代码库。他们真的是为了探索一小部分独立的 Swift。我经常发现自己在构建小型命令行应用程序而不是 Playground。对于非 UI 工作,命令行应用程序可能更强大。

【讨论】:

我肯定还有一些不太对劲的地方,这会返回 nil:let path = NSBundle.mainBundle().pathForResource("info", ofType: "plist", inDirectory:"ParsePlayground") .. 鉴于你所说的,mainBundle 似乎有问题 您的“Info.list”是否在 Playground 的“Resources”目录中名为“ParsePlayground”的目录中? mainBundle 是 Playground 编译安装到 build 目录后的 bundle。 看起来甚至 MyInfo.plist 都不会从资源中读取,但这无论如何都不会达到我的意图,因为我实际上想要一个真正的 plist 并且是从应用程序资源中提取的。感谢您的澄清——非常有帮助!

以上是关于向 info.plist 添加了自定义键,当我从 Swift 的游乐场访问时,它是 nil的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 将 DTXcode 密钥和其他密钥添加到 Info.plist

应用的 Info.plist 必须包含一个 NSContactsUsageDescription 键

在 Xcode 中向 info.plist 添加键

Cordova Plugin.xml 将未定义的键写入 info.plist

info.plist 上的本地化列表不完整

在构建之后(但在安装之前)向 Info.plist 数组添加值