iOS中与Android的registerActivityLifecycleCallbacks相当的方法是什么?

4
我开发了一个Android应用程序,使用application.registerActivityLifecycleCallbacks(http://developer.android.com/reference/android/app/Application.html)方法来记录每个Activity的启动和停止时间,并用于分析目的。现在我正在开发iOS版本,但是我找不到类似的方法来监视应用程序显示的UIViewControllers或UIView。
有人有想法吗?我是iOS初学者,可能没有采取正确的方法,请随意提出其他建议。
编辑 第一个答案后,我感觉应该更加准确。 实际上,我正在开发供其他开发人员将其包含在其应用程序中的SDK,因此我希望SDK对其代码的影响尽可能小。
我最初考虑过在所有Activity/UIViewController中扩展BaseActivity/BaseUIViewController,但这样做会很麻烦,而且由于两种语言都不允许多重继承,这将极大地影响他们的代码。这就是为什么在Android中registerActivityLifecycleCallbacks方法非常好,因为他们只需要给我一个Application或Activity对象。
是否有iOS的解决方案,或者我必须创建一个BaseController?
谢谢您的帮助。
2个回答

0

我在iOS中没有遇到与application.registerActivityLifecycleCallbacks类似的特定功能,但是您始终可以使用AppDelegate和每个类中存在的方法来实现自己的功能。

通过AppDelegate,您可以获取确定整个应用程序状态的方法,例如确定应用程序何时完成加载、何时进入后台等。有关这些状态的详细信息可以在UIApplicationDelegate Protocol Reference页面找到。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    NSLog("Application did finish launching with options: %@", launchOptions);
    return YES;
}

enter image description here

对于每个视图控制器,您可以在每个文件中的单独视图控制器生命周期方法中添加自己的实现。可用的方法包括viewDidLoadviewWillAppearviewDidAppearviewDidLayoutSubviews
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"View %@ did load", self);
}

谢谢你的回答,非常清晰和快速!然而我意识到我在问题上没有表述得足够清楚。实际上我正在开发一个供其他开发人员在其应用程序中包含的SDK,因此我希望SDK对其代码的影响尽可能小。这就是为什么在Android中registerActivityLifecycleCallbacks方法非常好,因为他们只需要给我一个Application或Activity对象即可。但是使用您的解决方案,他们将不得不在每个ViewController中实现一个BaseUIViewController,这可能有点繁重。 我会相应地编辑我的问题。 - Adrien B

0

虽然回答已经晚了,但或许对其他人有所帮助。要实现类似的行为,您可以使用“Swizzling”方法。以下是在Swift中解决方案的示例:

  1. 定义UIViewController扩展,包含您想要拦截的方法。例如:viewDidAppear(:)
extension UIViewController {   
  
    @objc func internal_viewDidAppear(_ animated: Bool) {
        self.internal_viewDidAppear(animated)// self here is the UIViewController which was appeared on the screen. Do with it whatever you want 
    } 
}
实现类似于这样的交换(swizzling)功能:
func swizzleViewDidAppear(){

    let clazz = UIViewController.self
    let originalSelector =  #selector(clazz.viewDidAppear(_:))
    let swizledSelector = #selector(clazz.internal_viewDidAppear(_:))    
    swizzle(originalClass: clazz, swizzledClass: clazz, originalSelector: originalSelector, swizzledSelector: swizledSelector)
}
主要的魔力在于混合搅拌:
func swizzle(originalClass: AnyClass, swizzledClass: AnyClass, originalSelector: Selector, swizzledSelector: Selector) {
    let originalMethod = class_getInstanceMethod(originalClass, originalSelector)
    let swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector)
    let didAddMethod = class_addMethod(originalClass, originalSelector, method_getImplementation(swizzledMethod!),method_getTypeEncoding(swizzledMethod!))
    if didAddMethod {
        class_replaceMethod(originalClass, swizzledSelector,method_getImplementation(originalMethod!),method_getTypeEncoding(originalMethod!))
    } else {
        method_exchangeImplementations(originalMethod!, swizzledMethod!)
    }
}
现在你需要在 SDK 启动时调用 swizzleViewDidAppear(最好在 viewDidLaunchWIthOptions 中)。这段代码让系统知道,它应该调用你的实现而不是原始的 viewDidAppear(:)。为了触发被拦截方法体中的原始实现,我们调用该方法本身。
注:
  1. Swizzling 应该每个会话只调用一次,所以你需要添加一些标志来指示是否已经调用了 swizzling,否则它将替换回原始的实现。
  2. 当开发者重写 viewDidAppear(:) 时,必须调用 super.viewDidAppear(animated),因为没有它,swizzling 将无法工作。
祝你好运和愉快的编码 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接