Swizzling SKStoreProductViewController viewWillAppear或viewDidAppear无法正常工作

时间:2015-05-26 15:58:57

标签: ios objective-c objective-c-runtime

我在浏览SKStoreProductViewController上的viewWillAppear或viewDidAppear时遇到了麻烦。我需要知道它的子类何时由第三方库提供。

我使用的代码是:

- (void)swizzleFunnyStoreProductControllerAppear {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(skViewDidAppearNotification:);
        NSString *viewControllerClassString = @"SKStoreProductViewController";

        Method originalMethod = class_getInstanceMethod(NSClassFromString(viewControllerClassString), originalSelector);
        Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);

        BOOL didAddMethod =
        class_addMethod(NSClassFromString(viewControllerClassString),
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        if (didAddMethod) {
            class_replaceMethod(NSClassFromString(viewControllerClassString),
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (void)skViewDidAppearNotification:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] postNotificationName:ALFunnyViewControllerDidAppearNotification object:NSStringFromClass([self class])];
    // calling the original method that is under the replaced name.
    [self skViewDidAppearNotification:animated];
}

运行时,我得到:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FunnySKStoreProductViewControllerSubClass skViewDidAppearNotification:]: unrecognized selector sent to instance 0x144f1b830'

在[self skViewDidAp ....]中使用断点显示响应选择器的类:

(lldb) po [self respondsToSelector:@selector(viewWillAppear:)]
true
(lldb) po [self respondsToSelector:@selector(viewDidAppear:)]
true
(lldb) po [self respondsToSelector:@selector(skViewDidAppearNotification:)]
false
(lldb) po [self respondsToSelector:@selector(skViewDidDisappearNotification:)]
true

我无法弄清楚为什么DidAppear的didAddMethod == NO,以及为什么它在DidDisappear的同一个类上工作?

1 个答案:

答案 0 :(得分:1)

我认为SKStoreProductViewController是使用远程XPC服务。 因此,您无法处理应用中的任何内容。 它可以通过其他系统进程处理。

如果您在recursiveDescription

上使用storeProductViewController.view

recursiveDescription

您可以找到_UIRemoteView