ios 使用 Swift 继承 UIApplication

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24020000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:19:24  来源:igfitidea点击:

Subclass UIApplication with Swift

ioscocoa-touchswift

提问by LombaX

In Objective C it was simple: it was sufficient to update the main.m file and change the UIApplicationMain() parameters

在 Objective C 中,这很简单:更新 main.m 文件并更改 UIApplicationMain() 参数就足够了

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

But in swift there is no main.m file, since the guide says

但是在 swift 中没有 main.m 文件,因为指南说

“Code written at global scope is used as the entry point for the program, so you don't need a main function.”

“在全局范围内编写的代码用作程序的入口点,因此您不需要主函数。”

So, how to subclass UIApplication in swift?? Any suggestion?

那么,如何在 swift 中继承 UIApplication ?有什么建议吗?

回答by LombaX

NOTEthe syntax has been updated for XCode 10.1 and Swift 5 in Jun 2019 ( credits to matt's answer here&& Tung Fam's answer here), if you are looking for the previous syntaxes look at the edit section.

注意XCode 10.1 和 Swift 5 的语法已于 2019 年 6 月更新(此处归功于matt 的回答&& Tung Fam 的回答),如果您正在寻找以前的语法,请查看编辑部分。

Ok, I've found the solution

好的,我找到了解决方案

First, I've noticed that, at the top of the AppDelegate.swift file, there is this line

首先,我注意到,在 AppDelegate.swift 文件的顶部,有这一行

@UIApplicationMain

Since this line is outside any scope (it's at file level), it's executed immediately, and I assume that the compiler translate it in a standard main function.

由于这一行在任何范围之外(它在文件级别),它会立即执行,并且我假设编译器将它转换为标准的 main 函数。

So, I did this, starting from a new Swift-Only application:

所以,我这样做了,从一个新的 Swift-Only 应用程序开始:

  • commented out @UIApplicationMain
  • added a main.swift file like this (FLApplication is my subclass).
    IMPORTANTthe file MUST BE NAMED main.swift, since top level statements are not supported on other files! You can't add the UIApplicationMain() call inside any other file, otherwise you'll receive this error:
  • 注释掉 @UIApplicationMain
  • 添加了一个像这样的 main.swift 文件(FLApplication 是我的子类)。
    重要的是文件必须命名为 main.swift,因为其他文件不支持顶级语句!您不能在任何其他文件中添加 UIApplicationMain() 调用,否则您将收到此错误:

Expressions are not allowed at the top level

顶层不允许使用表达式

This is the main.swift file

这是 main.swift 文件

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

Then, create a swift file for the UIApplication subclass, FLApplication.swift, with this code:

然后,使用以下代码为 UIApplication 子类 FLApplication.swift 创建一个 swift 文件:

import UIKit
import Foundation

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

now, UIApplication is correctly subclassed and you'll see the "send event" messages in the log

现在, UIApplication 被正确子类化,您将在日志中看到“发送事件”消息



OLD EDITS
For reference, since this has changed a lot from version 1 to version 3, I leave here all the previous edits

旧的编辑
作为参考,由于从版本 1 到版本 3 发生了很大变化,我将以前的所有编辑保留在这里



EDIT - MARCH 2015

编辑 - 2015 年 3 月

As commented by Hu Junfeng now the explanations about UIApplicationMainand the main.swift file are documented in the Attributes section of The Swift Language Reference: Link

正如UIApplicationMain胡俊峰所评论的,现在关于main.swift 文件的解释记录在 The Swift Language Reference 的 Attributes 部分:链接

As commented by Thomas Verbeek In the XCode 6.3 Beta, you might find that C_ARGC and C_ARGV have been renamed to Process.argc and Process.unsafeArgv respectively. Your UIApplicationMain call in the main.swift file will need updating to:

正如 Thomas Verbeek 所评论的,在 XCode 6.3 Beta 中,您可能会发现 C_ARGC 和 C_ARGV 已分别重命名为 Process.argc 和 Process.unsafeArgv。您在 main.swift 文件中的 UIApplicationMain 调用需要更新为:

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

The pre-XCode 8 syntax was

XCode 8 之前的语法是

import Foundation
import UIKit

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


EDIT - DEC 2016

编辑 - 2016 年 12 月

Solution for Xcode 8, before beta 6

Xcode 8,beta 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)
)

回答by Cezar

One alternative is to extend UIApplicationinstead of subclassing it. According to the iBookreleased by Apple, extensions in Swift can:

一种替代方法是扩展UIApplication而不是继承它。根据Apple 发布的iBook,Swift 中的扩展可以:

Add computed properties and computed static properties Define instance methods and type methods Provide new initializers Define subscripts Define and use new nested types Make an existing type conform to a protocol

Excerpt From: Apple Inc. “The Swift Programming Language.

添加计算属性和计算静态属性 定义实例方法和类型方法 提供新的初始值设定项 定义下标 定义和使用新的嵌套类型 使现有类型符合协议

摘自:Apple Inc.“Swift 编程语言。

If your needs in subclassing UIApplicationare satisfied by those capabilities, an Extension might be the way to go.

如果UIApplication这些功能满足了您在子类化中的需求,那么扩展可能是您要走的路。

回答by yoAlex5

  1. Create a subclass of UIApplicationand add your logic

    import UIKit
    
    class CustomUIApplication: UIApplication {
        override func sendEvent(_ event: UIEvent) {
            super.sendEvent(event)
        }
    }
    
  2. Create main.swiftfile where specify App Delegate and UIApplication.

    main.swiftcontains UIApplicationMain()global function[About]which is an entry point of your application that is called by OS. This function receives argument from called function, UIApplicationclass name, application delegate class name and runs loop

    import UIKit
    
    UIApplicationMain(
        CommandLine.argc,
        CommandLine.unsafeArgv,
    
        NSStringFromClass(CustomUIApplication.self), //was created at step 1
        NSStringFromClass(AppDelegate.self)
    )
    
  3. Remove/comment @UIApplicationMainin UIApplication.

    @UIApplicationMaingenerates main.swift.

    If you do not make it(step 2 is done) you get compile error - 'UIApplicationMain' attribute cannot be used in a module that contains top-level code

    //@UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        //...
    }
    
  1. 创建一个子类UIApplication并添加您的逻辑

    import UIKit
    
    class CustomUIApplication: UIApplication {
        override func sendEvent(_ event: UIEvent) {
            super.sendEvent(event)
        }
    }
    
  2. 创建main.swift文件,其中指定 App Delegate 和UIApplication.

    main.swift包含UIApplicationMain()global function[About],它是操作系统调用的应用程序的入口点。此函数从被调用的函数、UIApplication类名、应用程序委托类名和运行循环接收参数

    import UIKit
    
    UIApplicationMain(
        CommandLine.argc,
        CommandLine.unsafeArgv,
    
        NSStringFromClass(CustomUIApplication.self), //was created at step 1
        NSStringFromClass(AppDelegate.self)
    )
    
  3. 删除/评论@UIApplicationMainUIApplication

    @UIApplicationMain生成main.swift.

    如果你没有成功(第 2 步完成)你会得到编译错误 - 'UIApplicationMain' attribute cannot be used in a module that contains top-level code

    //@UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        //...
    }