SFSafariViewController blank in iOS 11/Xcode 9.0

I have a SFSafariViewController opening at the click of a button inside a UIActionSheet. It has been working fine and is still working fine on all the versions of iOS except iOS 11. Is there something they have changed regarding the SFSafariViewController in iOS 11 or in Xcode 9.0 that might have caused this issue?

UPDATE - So it seems like its Xcode 9.0 that is causing this issue. I have tried running it on different iOS versions and all of them seem to be giving this issue. It used to work fine when I ran it using Xcode 8.3.3, something I don't have anymore :(

Here's the code -

- (void)presentWebView:(NSString *)url {
url = [url stringByReplacingOccurrencesOfString:@" " withString:@"+"];
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *URL = [NSURL URLWithString:url];

if (URL) {
    if ([SFSafariViewController class] != nil) {
        SFSafariViewController *sfvc = [[SFSafariViewController alloc] initWithURL:URL];
        sfvc.delegate = self;
        [self.tabBarController presentViewController:sfvc animated:YES completion:nil];
    } else {
        if (![[UIApplication sharedApplication] openURL:URL]) {
            NSLog(@"%@%@",@"Failed to open url:",[url description]);
        }
    }
} else {
    // will have a nice alert displaying soon.
}

}

I've managed to fix this in my code. I hope this helps anyone else with a similar problem.

I had the exact same problem as described here. I tried everything above and unfortunately nothing worked.

In my app there were different windows. The fix was to ensure the window that would show SFSafariViewController was 'key' before presenting it. For example:

class MyViewController: UIViewcontroller {
    func showSafariViewController() {
        // imagine we have 2 windows, one for 'normal' content (key window) and one for 'other' content. lets say we're showing the 'other' content window, and have hidden the 'normal' window. you can see the 'other' content window in the app, but it won't be the key window!
        let window = // get the 'other' content window

        // make sure we make it the key window before presenting safari
        window.makeKey()

        // now present safari and celebrate victory by triumphantly slurping on your hot black coffee
        let mySafariViewController = SFSafariViewController(...)
        self.present(mySafariViewController ...)
    }
}

I suspect Apple are searching for a SFSafariViewController instance in the window UIApplication.shared.keyWindow. Perhaps they're adding a child view from somewhere else. In the documentation it states The user's activity and interaction with SFSafariViewController are not visible to your app, so perhaps it's the bug is something related to an added level of security https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller

SFSafariViewController blank in iOS 11/Xcode 9.0, Is there something they have changed regarding the SFSafariViewController in iOS 11 or in Xcode 9.0 that might have caused this issue? UPDATE - So it seems � SFSafariViewController(NSCoder) A constructor that initializes the object from the data stored in the unarchiver object. SFSafariViewController(NSObjectFlag) Constructor to call on derived classes to skip initialization and merely allocate the object. SFSafariViewController(NSUrl) Creates a new browsing interface with the provided URL.

Very similar to https://openradar.appspot.com/29108332

To fix it, you can disable the lazy loading of the view:

SFSafariViewController *viewController = [[SFSafariViewController alloc] init...];
(void)viewController.view;
...
[controller presentViewController:viewController animated:YES completion:nil];

SFSafariController loads URL fine …, SFSafariController loads URL fine in simulator but leaves a blank screen on device let safari = SFSafariViewController(url: url!, entersReaderIfAvailable: false). As of iOS 9.0, Apple allows you to embed Safari right into your app, which means you get its great user interface, you get its access to stored user data, and you even get Reader Mode right out of the box. To get started, import the SafariServices framework into your view controller, like this: import SafariServices

I have tried to do it using delay and make view of controller loading.Both are working for me.

Method 1. Using delay.

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
      let controller = SFSafariViewController(url: url)
      controller.modalPresentationStyle = .overFullScreen
      self.present(controller, animated: true, completion: nil)
      controller.delegate = self
    }

Method 2. Loading view.

      let controller = SFSafariViewController(url: url)
      let _ = controller.view
      controller.modalPresentationStyle = .overFullScreen
      self.present(controller, animated: true, completion: nil)
      controller.delegate = self

iOS11- SFSafariViewController. A controller contains webview., same as default SAFARI application. SFSafariViewController(SFSVC) came into existence from iOS-9 onwards. It's a way of opening webpage(� SFSafariViewController: With SFSafariViewController, you can use nearly all of the benefits of viewing web content inside Safari without forcing users to leave your app. Before iOS 9, the first two options were the only options for developers. Knowing when you had to use one or the other depended on the context of the presented content.

Update

Turns out the old answer didn't work, it just worked since I put breakpoints. If I added a thread sleep seems it worked in XCode9, but that's not the best solution. Anyone have another better solution?

SFSafariViewController *sfcontroller = [[SFSafariViewController alloc] initWithURL:url];
if (@available(iOS 11.0, *)) {
    [NSThread sleepForTimeInterval:0.5f];
}
sfcontroller.delegate = self;
[controller presentViewController:sfcontroller animated:NO completion:nil];

Old Answer

I have the same issue as genaks and tinkered around with SFViewController.

Seems like this code works for me

SFSafariViewController *sfcontroller = [[SFSafariViewController alloc] initWithURL:url];
if (@available(iOS 11.0, *)) {
    SFSafariViewControllerConfiguration *config = [[SFSafariViewControllerConfiguration alloc] init];
    config.barCollapsingEnabled = NO;
    sfcontroller = [[SFSafariViewController alloc] initWithURL:url configuration: config];
} else {
    // Fallback on earlier versions
}

sfcontroller.delegate = self;

[controller presentViewController:sfcontroller animated:YES completion:nil];

In ios 11, they introduce SFSafariViewControllerConfiguration, and by default the barCollapsingEnabled is true and it seems the one that causing my blank SafariView. Hope this solves yours too

How to use SFSafariViewController to show web pages in your app , If a user clicks a web link in your app, you used to have two options before iOS 9.0 came along: exit your app and launch the web page in Safari� To receive the latest developer news, visit and subscribe to our News and Updates.

We had this issue: our URL was https://our-side.com/index.html (an Angular site that would redirect to the /account route). When we removed the index.html, the SFSafariViewController loaded correctly!

iOS 9: Getting Started With SFSafariViewController, The real value of the safari view controller comes from understanding when to use it and, more importantly, why. Options for Showing Web� This year, Apple announced that starting with iOS 11, all instances of Safari will no longer share the same cookie space. This means that cookies set in the main Safari browser app are no longer readable from an instance of Safari within another app that could be created within a native app via the SFSafariViewController. This change was a

SFSafariViewController blank в iOS 11/Xcode 9.0, Очень похоже на https://openradar.appspot.com/29108332. Чтобы исправить это, вы можете отключить ленивую загрузку зрения: SFSafariViewController� SFSafariViewController on iOS 10 - not loading URL When presenting SFSafariViewController, the view controller appears but does not seem to load the URL. The same code, works as expected on iOS9.

ios, With iOS 9's launch earlier this week, it's never been a better time to understand how to or in the simulator (Xcode 7.0 or later is required as we're accessing the iOS 9 SDK). doesn't result in empty Safari tabs (a longstanding problem with iOS 8 and below). Now supports Xcode 11, Swift 5 and iOS 13. Initializes a Safari view controller that will load the specified URL, entering Reader mode if Reader mode is requested and available.

Working with Search APIs and SFSafariViewController in iOS 9, Building with Firebase now requires Xcode 11.3 or higher. Fixed display issue with banner messages on iPad Pro 11" (#4714). Minimum iOS version is now 9.0. Fixed an issue that caused us to drop empty objects from calls to setData(.. ., in google_mobile_app_ads.js opens URLs in SFSafariViewController . On iOS 12.2 and above, if an objects command (be it an automation or usage of object spy) was performed in an SFSafariViewController in an app which has not been signed with a developer certificate, a device reboot may be required to allow DOM objects interaction in SFSafariViewControllers on apps which have been signed correctly.

Comments
  • can you show your tried code, ios11 has modified
  • @Anbu.Karthik added the code
  • This fixed my problem! Thank you! PS: You can easily get the root window by using UIApplication.shared.windows[0] (maybe that'll help someone)
  • I'm using the method like suggested but getting issue - Unbalanced calls to begin/end appearance transitions for <UIViewController: 0x7fab0d301990>.
  • @Apple unfortunately i'm not sure what to advise without seeing any code - there could be a few reasons for this that are unrelated to this thread. might be worth starting a new thread? else maybe read this and see if it helps stackoverflow.com/questions/9088465/…
  • by the way what does this - (void)viewController.view; - do?
  • this causes the view to load: "If you access this property and its value is currently nil, the view controller automatically calls the loadView() method and returns the resulting view."
  • Worked for me!!
  • Method two fixed the issue on iOS 12 with Xcode 11. The issue doesn't show up on iOS 13.
  • Works but like you said not a good solution. By the way what's so magical about that 0.5 because I tried reducing it and it didn't work.
  • And after working once, this has stopped working too. The SafariViewController is still blank
  • what if I need animation?
  • even if it works - it is totally incorrect to replace rootViewController to show SFSafariViewController only