Google Plus Sign in iOS using UIWebView

后端 未结 3 1127
慢半拍i
慢半拍i 2020-12-31 03:07

I am using google+ sign in my app using the Google Plus SDK. When the user taps on the sign in button the user gets redirected to safari. (Standard Process).

However

3条回答
  •  难免孤独
    2020-12-31 03:19

    I tried merging sample apps for Gmail API and GooglePlus to use UIWebView login instead of Safari and it seems to work:

    1. create google project BUT when setting up credentials Installed application type choose Other
    2. add/enable Google+ API to your google project
    3. add/enable Gmail API to google project
    4. follow Google+ instructions and add all frameworks and drag ONE BY ONE GoogleOpenSource.framework, GooglePlus.framework and GooglePlus.bundle (you may not need this since we are not using SignInButton, well just in case it is there) in your project
    5. add other linker flags -all_load -ObjC, disable ARC
    6. DRAG GTMOAuth2ViewTouch.xib into your project files (from OAuth2)

    enter image description here

    my viewcontroller .h file I added 2 buttons to login and retrieve data, textview to display retrieved data, connected them in the builder. ALSO added interface and property for GTMOAuth2Authentication:

    #import 
    #import 
    #import 
    
    @interface MyViewController : UIViewController{
    IBOutlet UIButton *loginBttn;
    IBOutlet UIButton *retriveBttn;
    IBOutlet UITextView *profileTextView;
    
    GTMOAuth2Authentication *mAuth;
    }
    
    @property (retain, nonatomic) IBOutlet UIButton *loginBttn;
    @property (retain, nonatomic) IBOutlet UIButton *retriveBttn;
    @property (nonatomic, retain) IBOutlet UITextView *profileTextView;
    
    @property (nonatomic, retain) GTMOAuth2Authentication *auth;
    
    -(IBAction)dologin;
    -(IBAction)doretrive;
    
    @end
    

    my viewcontroller .m file:

    #import "MyViewController.h"
    #import "AppDelegate.h"
    #import 
    #import 
    
    static NSString *const kKeychainItemName = @"Google OAuth2 For gglplustest";
    static NSString *const kClientID = @"your client id";
    static NSString *const kClientSecret = @"your client secret";
    
    @interface MyViewController ()
    @end
    
    @implementation MyViewController
    @synthesize loginBttn,retriveBttn;
    @synthesize auth = mAuth;
    @synthesize profileTextView;
    
    -(IBAction)doretrive{
        GTLServicePlus* plusService = [[[GTLServicePlus alloc] init] autorelease];
        plusService.retryEnabled = YES;
    
        [plusService setAuthorizer:self.auth];//!!!here use our authentication object!!!
    
        GTLQueryPlus *query = [GTLQueryPlus queryForPeopleGetWithUserId:@"me"];
    
        [plusService executeQuery:query
                completionHandler:^(GTLServiceTicket *ticket,
                                    GTLPlusPerson *person,
                                    NSError *error) {
                    if (error) {
                        GTMLoggerError(@"Error: %@", error);
                    } else {
                        // Retrieve the display name and "about me" text
                        [person retain];
                        NSString *description = [NSString stringWithFormat:
                                                 @"%@\n%@\n%@", person.displayName,
                                                 person.aboutMe,person.emails];
                        [profileTextView setText:description];
                    }
                }];
    }
    
    - (void)auth:(GTMOAuth2Authentication *)auth finishedRefreshWithFetcher:(GTMHTTPFetcher *)fetcher error:(NSError *)error {
        [self viewController:nil finishedWithAuth:auth error:error];
         if (error != nil) {
         // Refresh failed
             NSLog(@"Authentication Error %@", error.localizedDescription);
             self.auth=nil;
             return;
         }
         self.auth=auth;
    }
    
    - (void)viewController:(GTMOAuth2ViewControllerTouch *)viewController finishedWithAuth:(GTMOAuth2Authentication *)auth error:(NSError *)error
    {
        if (error != nil) {
            // Authentication failed
            NSLog(@"Authentication Error %@", error.localizedDescription);
            self.auth=nil;
            return;
        }
        self.auth=auth;
        [viewController release];//no ARC
    }
    
    -(IBAction)dologin{
        NSString *scope = kGTLAuthScopePlusLogin;//Google+ scope
        GTMOAuth2Authentication * auth = [GTMOAuth2ViewControllerTouch 
        authForGoogleFromKeychainForName:kKeychainItemName
        clientID:kClientID
        clientSecret:kClientSecret];
        if ([auth refreshToken] == nil) {
            GTMOAuth2ViewControllerTouch *authController;
            authController = [[GTMOAuth2ViewControllerTouch alloc] 
            initWithScope:scope 
            clientID:kClientID 
            clientSecret:kClientSecret  
            keychainItemName:kKeychainItemName
            delegate:self
            finishedSelector:@selector(viewController:finishedWithAuth:error:)];
            [[self navigationController] pushViewController:authController animated:YES];
        }else{
            [auth beginTokenFetchWithDelegate:self didFinishSelector:@selector(auth:finishedRefreshWithFetcher:error:)];
        }
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    

    So now, when view is loaded it does not try to login.

    Then on a view when I touch loginBttn that will run dologin method (from GmailMail sample) where I setup the scope to GooglePlus: 1st it will check if there is saved info in keychain, if it is, it will proceed without asking you to login. If not, it will do it as for Gmail login in UIWebView directly inside my app.

    enter image description here

    here how it looks after login:

    enter image description here

    Then I can touch retriveBttn to run retrieve method (e.g. to get Name, About and emails) that uses GooglePlus sample HOWEVER I set Authorizer to the authenticator that I saved after successful login like that: [plusService setAuthorizer:self.auth];

    here is the view before and after retrieve is complete:

    enter image description here

    enter image description here

    Seems like it is doing what is is supposed to.

提交回复
热议问题