Подкласс UIApplication с Swift

В Objective C это было просто: достаточно было обновить файл main.m и изменить параметры UIApplicationMain()

return UIApplicationMain(argc, argv, NSStringFromClass([CustomUIApplication class]), NSStringFromClass([AppDelegate class]));

Но в swift нет файла main.m, так как руководство говорит

"Код, написанный в глобальной области, используется как точка входа для программы, поэтому вам не нужна основная функция".

Итак, как подклассы UIApplication в swift?? Любое предложение?

Ответ 1

ПРИМЕЧАНИЕ. Синтаксис был обновлен для XCode 10.1 и Swift 5 в июне 2019 года (кредиты на матовый ответ здесь и ответ на Tung Fam здесь), если вы ищете предыдущие синтаксисы, посмотрите раздел редактирования.

Хорошо я нашел решение

Во-первых, я заметил, что в верхней части файла AppDelegate.swift есть эта строка

@UIApplicationMain

Так как эта строка находится вне какой-либо области (она находится на уровне файла), она выполняется немедленно, и я предполагаю, что компилятор переведет ее в стандартную основную функцию.

Итак, я сделал это, начиная с нового приложения Swift-Only:

  • закомментировано @UIApplicationMain
  • добавил файл main.swift, как этот (FLApplication мой подкласс).
    ВАЖНО, файл ДОЛЖЕН БЫТЬ НАЗВАН main.swift, так как операторы верхнего уровня не поддерживаются в других файлах! Вы не можете добавить вызов UIApplicationMain() в любой другой файл, иначе вы получите эту ошибку:

Выражения не допускаются на верхнем уровне

Это файл main.swift

UIApplicationMain(
    CommandLine.argc, CommandLine.unsafeArgv, 
    NSStringFromClass(FLApplication.self), NSStringFromClass(AppDelegate.self)
)

Затем создайте файл swift для подкласса UIApplication, FLApplication.swift, с этим кодом:

import UIKit
import Foundation

class FLApplication: UIApplication {
    override func sendEvent(_ event: UIEvent) {
        super.sendEvent(event)
        print("send event")
    }
}

Теперь UIApplication правильно разделен на подклассы, и вы увидите сообщения "send event" в журнале


СТАРЫЕ РЕДАКТЫ
Для справки, так как это сильно изменилось с версии 1 до версии 3, я оставляю здесь все предыдущие изменения


РЕДАКТИРОВАТЬ - МАРТ 2015

Как прокомментировал Ху Цзюньфэн, теперь объяснения относительно UIApplicationMain и файла main.swift документированы в разделе Атрибуты Справочника по языку Swift: Ссылка

Как прокомментировал Томас Вербик В бета-версии XCode 6.3 вы можете обнаружить, что C_ARGC и C_ARGV были переименованы в Process.argc и Process.unsafeArgv соответственно. Ваш вызов UIApplicationMain в файле main.swift необходимо обновить до:

UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(FLApplication), NSStringFromClass(AppDelegate))

Синтаксис до XCode 8 был

import Foundation
import UIKit

UIApplicationMain(C_ARGC, C_ARGV, NSStringFromClass(FLApplication), NSStringFromClass(AppDelegate))

РЕДАКТИРОВАТЬ - ДЕКАБРЬ 2016

Решение для Xcode 8, до бета 6

import Foundation
import UIKit

UIApplicationMain(
    CommandLine.argc,
    UnsafeMutableRawPointer(CommandLine.unsafeArgv)
        .bindMemory( 
            to: UnsafeMutablePointer<Int8>.self, 
            capacity: Int(CommandLine.argc)),
    NSStringFromClass(FLApplication.self),
    NSStringFromClass(AppDelegate.self)
)

Ответ 2

Одна альтернатива - расширить UIApplication вместо того, чтобы UIApplication его подклассы. Согласно iBook, выпущенному Apple, расширения в Swift могут:

Добавить вычисляемые свойства и вычисленные статические свойства. Определить методы экземпляров и методы типов. Предоставить новые инициализаторы. Определить индексы. Определить и использовать новые вложенные типы. Привести существующий тип в соответствие с протоколом.

Выдержка из: Apple Inc. "Язык программирования Swift.

Если эти возможности удовлетворяют вашим потребностям в UIApplication подклассов UIApplication, возможно, стоит использовать расширение.

Ответ 3

Полное решение (Swift 5, Xcode 10.2.1)

В принятом ответе отсутствует один важный шаг. Выполните полное решение из 4 шагов:

  1. В AppDelegate удалите как @UIApplicationMain
  2. Создайте файл с точным именем main.swift. Добавьте этот код:
import UIKit
UIApplicationMain(
    CommandLine.argc, CommandLine.unsafeArgv,
    nil, NSStringFromClass(AppDelegate.self)
)
  1. Создайте подкласс UIApplication:
import UIKit
@objc(MyApplication) class MyApplication: UIApplication {
    override func sendEvent(_ event: UIEvent) {
        super.sendEvent(event)
        print("send event")
    }
}
  1. Добавьте это в info.plist:
<key>NSPrincipalClass</key>
<string>MyApplication</string>

Так это выглядит так: enter image description here

Вы сделали!