我开发了一个 Android 应用程序,其中使用 application.registerActivityLifecycleCallbacks (http://developer.android.com/reference/android/app/Application.html) 来了解每个 Activity 何时启动和停止并记录下来以供分析目的。我现在正在开发iOS版本,我找不到与此方法等效的方法来监视应用程序显示的UIViewControllers或UIView。
有人有想法吗?我是 iOS 初学者,所以我可能没有采取正确的方法,请随意提出其他想法。
编辑
在第一次回答之后,我觉得我应该更准确。
我实际上正在为其他开发人员开发一个 SDK,以便将其包含在他们的应用程序中,因此我希望 SDK 对他们的代码的影响尽可能小。
我首先考虑做一个
BaseActivity
/BaseUIViewController
,开发人员必须在所有 Activity
/UIViewController
中进行扩展,但感觉很重,而且由于两种语言都不允许 多重继承,这会极大地影响他们的代码。这就是为什么 registerActivityLifecycleCallbacks
方法在 Android 中很棒,因为它们只需要给我一个 Application
或 Activity
对象。
有适用于 iOS 的解决方案吗?还是我必须创建一个 BaseController ?
提前谢谢您。
我还没有遇到过 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;
}
对于每个视图控制器,您可以将实现添加到每个文件中的各个视图控制器生命周期方法中。可以使用
viewDidLoad
、viewWillAppear
、viewDidAppear
和 viewDidLayoutSubviews
等方法。
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"View %@ did load", self);
}
现在回答已经太晚了,但也许对其他人有帮助。要实现类似的行为,您可以使用“Swizzling”方法。下面是 Swift 中解决方案的示例:
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 } }
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(:) 实现。为了触发拦截方法体内的原始实现,我们调用方法本身。
备注:
每个会话应该调用一次 Swizzling,因此您需要添加一些标志来指示 swizzling 已经被调用,否则它将把实现替换回原来的状态。
当开发人员重写 viewDidAppear(:) 时,必须调用
super.viewDidAppear(animated)
,因为没有它,swizzling 将无法工作。
祝你好运,编码愉快:)