如何以编程方式在iOS8上创build一个Today小部件?

我试图删除故事板文件和相关的Info.plist条目,但这次扩展停止工作; 它甚至不从XCode启动。

The operation couldn't be completed. (LaunchServicesError error 0.)

在常规应用程序(包含应用程序)上很容易,因为我们看到它是入口点和应用程序委托,但是如何在扩展上进行呢?

我做了以下步骤:

  • 从您的项目中删除故事板文件
  • 修改info.plist:

转到NSExtension字典,删除这个键:NSExtensionMainStoryboard。 用这个键NSExtensionPrincipalClassreplace它,并添加你的ViewController作为值,例如TodayViewController。

之前:

 <key>NSExtension</key> <dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.widget-extension</string> </dict> 

后:

 <key>NSExtension</key> <dict> <key>NSExtensionPrincipalClass</key> <string>TodayViewController</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.widget-extension</string> </dict> 
  • 如果您使用Swift,则必须在目标的“生成设置”中启用“embedded式内容包含Swift代码”。 将其设置为YES。
  • 此外,我不得不在我的TodayViewController类(导入后@objc (TodayViewController)添加@objc (TodayViewController) )。

该应用程序应该现在运行。 但还有另外两件事情我必须做:

  • 创build一个视图。 显然没有自动创build的视图。

所以添加这些行:

 override func loadView() { view = UIView(frame:CGRect(x:0.0, y:0, width:320.0, height:200.0)) } 
  • 并在你的viewDidLoad方法中设置你的小部件的高度: self.preferredContentSize = CGSizeMake(0, 200)

Info.plist删除NSExtensionMainStoryboard添加NSExtensionPrincipalClass = YourViewController

不要忘记在loadView创build自己的视图

FWIW,它不工作,直到我为我的Swift视图控制器类添加模块名称的前缀,例如

 <key>NSExtension</key> <dict> <!-- ... --> <key>NSExtensionPrincipalClass</key> <string>SafariActionExtension.RootViewController</string> <!-- ... --> </dict> 

这可能是因为Swift模块的类查找将模块名称转换为类名的前缀。 例如,要在代码中创build类,可以编写NSStringFromClass("SafariActionExtension.RootViewController") ,因此是前缀。