I am trying to create a share extension for my application which requires to login to Google from the extension. I've setup the sharing group keychain and am able to write from the main application and read the extension target. But I can't login to Google from the extension because GIDSignIn.sharedInstance().hasAuthInKeychain()
always returns false.
Is there any way to login to Google from an extension and how do I do that? Any help would be appreciated.
App Extensions are an iOS feature that allows developers to extend the functionality and content of their app beyond the app itself, making it available to users in other apps or in the main operating system.
The extension displays its view within the context of the host app and then uses the items it received in the host app's request to perform its task (in this example, the extension receives the selected text). In step 3 of Figure 2-1, the user performs or cancels the task in the app extension and dismisses it.
import <GoogleSignIn/GoogleSignIn.h> import <Google/Core.h>
import Google
In application:didFinishLaunchingWithOptionslaunchOptions:
configure the GGLContext
object:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { var configureError: NSError? GGLContext.sharedInstance().configureWithError(&configureError) assert(configureError == nil, "Error configuring Google services: \(configureError)") GIDSignIn.sharedInstance().clientID = "client id" GIDSignIn.sharedInstance.shouldFetchBasicProfile = true GIDSignIn.sharedInstance().delegate = self }
Then, add a GIDSignInButton
view to your app.
Lastly, in the view controller, implement the signIn:didSignInForUser:
delegate method that will be called when the sign-in button is tapped:
when authorizing the app.
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error { // Perform any operations on signed in user here. // ... }
When you sign-in the Google framework will have to use native iOS methods to add the new credentials to the iOS Keychain. Thus they will be using the SecItemAdd(_:_:)
method that will add one or more items to a keychain.
To access the same keychain item in both the app and the extension, you need to enable the "Keychain Sharing" for both the app and the extension from the Xcode's Capabilities section in your project settings. When you do this, Xcode will probably want to update your app ID and provisioning profiles, because they need to reflect this new capability. You'll probably have to reauthorize the app (Step 2) to get the credentials into the right group.
Apple Documentation clearly states:
If you want the new keychain item to be shared among multiple applications, include the kSecAttrAccessGroup key in the attributes dictionary. The value of this key must be the name of a keychain access group to which all of the programs that will share this item belong.
When you use Xcode to create an application, Xcode adds an application-identifier entitlement to the application bundle. Keychain Services uses this entitlement to grant the application access to its own keychain items. You can also add a keychain-access-groups entitlement to the application and, in the entitlement property list file, specify an array of keychain access groups to which the application belongs.
Please see "Google Sign-In for iOS". Here is sample code to use GIDSignIn
:
GIDSignIn
shared instance: GIDSignIn *signIn = [GIDSignIn sharedInstance];
[signIn setScopes:[NSArray arrayWithObject:@"https://www.googleapis.com/auth/plus.login"]];
[signIn setDelegate:self];
signIn:didSignInForUser:withError:
.handleURL
on the shared instance from application:openUrl:
... in your app delegate.signIn
on the shared instance;If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With