iOS10 SFSafariViewController not working when alph

2019-01-25 12:50发布

问题:

I'm using SFSafariViewController to grab user's cookie in my app. Here's is my code:

SFSafariViewController *safari = [[SFSafariViewController alloc]initWithURL:[NSURL URLWithString:referrerUrl] entersReaderIfAvailable:NO];
    safari.delegate = self;
    safari.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    safari.view.alpha = 0.0;
    safari.view.hidden = true;
    [self dismissViewControllerAnimated:false completion:nil];
    NSLog(@"[referrerService - StoreViewController] presenting safari VC");
    [self presentViewController:safari animated:false completion:nil];

This works well on iOS 9. but on iOS 10 it seems that the SF controller doesn't work (it also block my current context - which happens to be another UIWebView).

Anyone can suggest of an alternative way to hide a SFSafariViewController?

回答1:

Updated answer:

Apple prohibits this kind of SafariViewController usage in last version of review guidelines:

SafariViewContoller must be used to visibly present information to users; the controller may not be hidden or obscured by other views or layers. Additionally, an app may not use SafariViewController to track users without their knowledge and consent.

Old answer:

In iOS 10 there are some additional requirements for presented SFSafariViewController:

1) Your view should not be hidden, so hidden should be set to NO

2) The minimum value for alpha is 0.05

3) You need to add controller manually with addChildViewController: / didMoveToParentViewController: (callback's doesn't called otherwise).

4) UIApplication.keyWindow.frame and SFSafariViewController.view.frame should have non-empty intersection (in appropriate coordinate space), that means:

  • safari view size should be greater than CGSizeZero

  • you can't place safari view off the screen

  • but you can hide safari view under your own view

Code example:

self.safariVC = [[SFSafariViewController alloc] initWithURL:referrerUrl];
self.safariVC.delegate = self;
self.safariVC.view.alpha = 0.05;
[self addChildViewController:self.safariVC];
self.safariVC.view.frame = CGRectMake(0.0, 0.0, 0.5, 0.5);
[self.view insertSubview:self.safariVC.view atIndex:0];
[self.safariVC didMoveToParentViewController:self];

Also, don't forget to remove safariVC properly after the end of the usage:

[self.safariVC willMoveToParentViewController:nil];
[self.safariVC.view removeFromSuperview];
[self.safariVC removeFromParentViewController];


回答2:

New info: Don't do this. The revised App Store guidelines prohibit this practice.

https://developer.apple.com/app-store/review/guidelines/

I'll leave this below for posterity: I call the following code from my app delegate's didFinishLaunchingWithOptions.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self checkCookie];
}

- (void)checkCookie
{
    NSURL *url = [NSURL URLWithString:@"http://domainToCheck.com"];
    SFSafariViewController *vc = [[SFSafariViewController alloc] initWithURL:url];
    vc.delegate = self;

    UIViewController *windowRootController = [[UIViewController alloc] init];

    self.secondWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.secondWindow.rootViewController = windowRootController;
    [self.secondWindow makeKeyAndVisible];
    [self.secondWindow setAlpha:0.1];

    [windowRootController presentViewController:vc animated:NO completion:nil];
    self.window.windowLevel = 10;
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options
{
    [self.secondWindow.rootViewController dismissViewControllerAnimated:NO completion:nil];
    self.secondWindow = nil;
    self.window.windowLevel = 0;

    return YES;
}


回答3:

I was able to achieve this affect using invisible child view controller:

_safariViewController = [[SFSafariViewController alloc] initWithURL:_requestURL];
_safariViewController.delegate = self;
_safariViewController.view.userInteractionEnabled = NO;
_safariViewController.view.alpha = 0.0;
[_containerViewController addChildViewController:_safariViewController];
[_containerViewController.view addSubview:_safariViewController.view];
[_safariViewController didMoveToParentViewController:_containerViewController];
_safariViewController.view.frame = CGRectZero;


回答4:

its possible to use this on swift 3 for xcode 8.3.2 becausa i get all i delegate anduse correctly , but i have this error

[12:05] 2017-04-25 12:05:03.680 pruebaslibrary[7476:136239] Warning: Attempt to present on whose view is not in the window hierarchy!