Как создать виджет "Сегодня" программно без раскадровки на iOS8?

Я попытался удалить файл раскадровки и связанную с ним запись Info.plist, но на этот раз расширение перестало работать; он даже не запускается из XCode.

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

Это легко для обычного приложения (содержащего приложение), поскольку мы видим его точку входа и делегата приложения, но как это сделать и на расширениях?

Ответы

Ответ 1

Удалите NSExtensionMainStoryboard из Info.plist Добавить NSExtensionPrincipalClass = YourViewController

Не забудьте создать свой собственный вид в loadView

Ответ 2

Я сделал следующие шаги:

  • Удалите файл раскадровки из вашего проекта
  • Измените info.plist:

Перейдите в словарь NSExtension, удалите этот ключ: NSExtensionMainStoryboard. Замените его этим ключом NSExtensionPrincipalClass и добавьте 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, вам нужно включить "Встроенный контент содержит Swift Code" в настройках сборки цели. Установите значение YES.
  • Кроме того, мне пришлось добавить @objc (TodayViewController) в мой класс TodayViewController (после импорта).

Приложение должно запускаться прямо сейчас. Но мне пришлось еще две вещи:

  • Создайте представление. Очевидно, что автоматически создается представление.

Итак, добавьте следующие строки:

override func loadView()
{
    view = UIView(frame:CGRect(x:0.0, y:0, width:320.0, height:200.0))
}
  • И установите высоту вашего виджета в методе viewDidLoad: self.preferredContentSize = CGSizeMake(0, 200)

Ответ 3

FWIW, это не сработало для меня, пока я не добавил префикс имени модуля для моего класса контроллера вида Swift, например.

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

Это, вероятно, потому, что поиск классов для модулей Swift превращает имена модулей в префикс для имени класса. Например. для создания вашего класса в коде вы должны написать NSStringFromClass("SafariActionExtension.RootViewController"), следовательно, префикс.