【问题标题】:How to programmatically dismiss system dialogs like "<App> would like to access your photos"?如何以编程方式关闭系统对话框,如“<App> 想要访问您的照片”?
【发布时间】:2013-10-09 17:51:38
【问题描述】:

有没有办法以编程方式关闭对话框,例如应用想要访问照片、访问联系人和访问位置的对话框?

我认为有一种方法可以混合 API 方法,但我真的不知道是哪一种。找出哪些方法需要混合的方法是什么?如果调配不是方式,那么还有什么替代方法?

请注意,这不是针对产品的,仅用于测试,因此如果可行的话,swizzling 是一个不错的选择。

【问题讨论】:

  • 我不认为你可以弹出系统对话框。当您尝试访问设置中未启用的 API 时会显示它们。
  • 你知道这永远不会在应用商店应用中出现,对吧?
  • 是的,我知道。这就是为什么我添加为注释,不是为了发布。只是测试目的。
  • 我知道对于位置对话框,您可以调动 CLLocationManager 的 startUpdatingLocation 方法什么都不做,这样可以避免对话框。我不知道照片或地址簿。

标签: iphone objective-c dialog


【解决方案1】:

1。覆盖“访问联系人”对话框

在您的 UIApplicationDelegate 实现中键入此代码(需要导入 &lt;AddressBook/AddressBook.h&gt;

ABAuthorizationStatus ABAddressBookGetAuthorizationStatus(void) {
  return kABAuthorizationStatusAuthorized;
}

2。创建一个 swizzling 方法:

在您的UIApplicationDelegate 实现中输入以下方法,或者在您需要的任何地方,最好使用辅助类。 (需要导入&lt;objc/runtime.h&gt;

- (void)swizzleSelector:(SEL)selector fromInstancesOfClass:(Class)clazz withBlock:(id)block {
  id replaceBlock = Block_copy(block);
  Method origMethod = class_getInstanceMethod(clazz, selector);
  IMP origImpl = method_getImplementation(origMethod);
  IMP replaceImpl = imp_implementationWithBlock(replaceBlock);
  method_setImplementation(origMethod, replaceImpl);
}

- (void)swizzleSelector:(SEL)selector fromClass:(Class)clazz withBlock:(id)block {
  id replaceBlock = Block_copy(block);
  Method origMethod = class_getClassMethod(clazz, selector);
  IMP origImpl = method_getImplementation(origMethod);
  IMP replaceImpl = imp_implementationWithBlock(replaceBlock);
  method_setImplementation(origMethod, replaceImpl);
}

3。覆盖“访问位置”对话框:

在您的 UIApplicationDelegate 实现中执行以下操作。 (需要导入&lt;CoreLocation/CoreLocation.h&gt;):

[self swizzleSelector:@selector(startUpdatingLocation) fromInstancesOfClass:[CLLocationManager class] withBlock:^{}];
[self swizzleSelector:@selector(startMonitoringSignificantLocationChanges) fromInstancesOfClass:[CLLocationManager class] withBlock:^{}];
[self swizzleSelector:@selector(locationServicesEnabled) fromClass:[CLLocationManager class] withBlock:^{ return NO; }];

4。覆盖“访问照片”对话框:

在您的 UIApplicationDelegate 实施中执行以下操作。 (需要导入&lt;AssetsLibrary/AssetsLibrary.h&gt;):

[self swizzleSelector:@selector(authorizationStatus) fromClass:[ALAssetsLibrary class] withBlock:^{ return ALAuthorizationStatusAuthorized; }];
[self swizzleSelector:@selector(enumerateGroupsWithTypes:usingBlock:failureBlock:) fromInstancesOfClass:[ALAssetsLibrary class] withBlock:^{}];

【讨论】:

    【解决方案2】:

    您应该能够像这样从应用中的任何位置访问警报。这适用于常规警报,但我没有尝试使用系统警报(它们可能与常规警报不在同一层次结构中,在这种情况下您根本无法访问它们)。如果它确实有效,并且您尝试使用它发布应用程序,它几乎肯定会被拒绝。

    for (UIWindow* w in [UIApplication sharedApplication].windows)
    {
        for (NSObject* o in w.subviews)
            if ([o isKindOfClass:[UIAlertView class]])
            {
                // as an example, this will just dismiss/cancel the alert
                [(UIAlertView*)o dismissWithClickedButtonIndex:[(UIAlertView*)o cancelButtonIndex] animated:YES];
            }
    }
    

    【讨论】:

    • 由于此问题中提到的这些对话框不是应用程序对话框,而是特定于操作系统的对话框,因此此代码将不起作用。
    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    相关资源
    最近更新 更多