Google (and others) require that oAuth login flows go through an external browser (to avoid phishing scams etc.)
“In the coming months, we will no longer allow OAuth requests to Google in embedded browsers known as “web-views”, such as the WebView UI element on Android and UIWebView/WKWebView on iOS, and equivalents on Windows and OS X.”
However, Apple is now rejecting binary updates that open an external browser. They REQUIRE using the Safari View Controller API (SFSafariViewController).
I’m surprised that this isn’t biting everybody right now - maybe they’re slowly starting to squeeze or maybe not that many people are dealing with oauth or maybe google isn’t squeezing all requests yet?
In any case - due to this requirement, is it something that Unity can provide? I didn’t see anything on the Asset Store yet.
Alternatively, it seems like writing a plugin to swap Application.OpenURL() for this wouldn’t be too much code to write… especially if url schemes work to get back to the app
Does anyone have a snippet of objective-c to pop into the plugins folder that would handle this?
this works on ios to open SFSafariViewController with a given url (put into Plugins/ios/SafariView.mm)
#import <SafariServices/SafariServices.h>
extern UIViewController * UnityGetGLViewController();
extern void UnitySendMessage( const char * className, const char * methodName, const char * param );
extern "C"
{
@interface SafariViewController : UIViewController<SFSafariViewControllerDelegate>
// ...
@end
@implementation SafariViewController
- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller {
NSLog(@"safariViewControllerDidFinish");
UnitySendMessage("YourSignInGameObject", "OnAuthCompleted", "");
}
@end
SafariViewController * svc;
void launchUrl(const char * url)
{
NSLog(@"Launching SFSafariViewController");
// Get the instance of ViewController that Unity is displaying now
UIViewController * uvc = UnityGetGLViewController();
// Generate an NSURL object based on the C string passed from C#
NSURL * URL = [NSURL URLWithString: [[NSString alloc] initWithUTF8String:url]];
// Create an SFSafariViewController object from the generated URL
SFSafariViewController * sfvc = [[SFSafariViewController alloc] initWithURL:URL];
// Assign a delegate to handle when the user presses the 'Done' button
svc = [[SafariViewController alloc] init];
sfvc.delegate = svc;
// Start the generated SFSafariViewController object
[uvc presentViewController:sfvc animated:YES completion:nil];
NSLog(@"Presented SFSafariViewController");
}
void dismiss()
{
UIViewController * uvc = UnityGetGLViewController();
[uvc dismissViewControllerAnimated:YES completion:nil];
}
}
Then C# wrapper to call it:
using System.Runtime.InteropServices;
using UnityEngine;
public static class SFSafariView
{
#if UNITY_IOS
[DllImport("__Internal")]
extern static void launchUrl(string url);
[DllImport("__Internal")]
extern static void dismiss();
#endif
public static void LaunchUrl(string url)
{
#if UNITY_IOS
launchUrl(url);
#endif
}
public static void Dismiss()
{
#if UNITY_IOS
dismiss();
#endif
}
}
Remember also to select SafariView.mm in your Unity project, then in the Inspector expand Rarely used services and tick SafariServices to ensure this compiles.
Note the usage of UnitySendMessage within the SFSafariViewControllerDelegate class implementation to notify your C# script that the user pressed the Done button.
I have been successful in getting custom url to launch the app from safari app post facebook authentication.
Now I am trying to get it to work with SFSafariViewController. The custom url call does not make any difference at all.
How do I get this working? I am very new to ios development. Am I missing anything?
Alternatively, in this line below, I want to send the uri received from facebook to my gameobject
I had the same problem, and I found that the EntryPointNotFoundException get raised when you try to run the code under Unity Editor (Windows or MacOSX, it’s the same).
You need to be sure to run it exclusively when you’re in UNITY_IOS mode, so on a “real” IOS Device.
I implemented this and it works perfectly on an iOS device. Thanks a lot for a clean and easy solution. What I now need is a callback in Unity once the web page has finished loading by the SFSafariView controller.