14

最近、アプリに Google + API を統合しましたが、簡単でした。唯一の問題は、アプリを離れてから戻る必要があることです (これには URL スキームが使用されます)。これは私が望む動作ではありません。LinkedIn API のように、サービスを直接呼び出して、応答を処理する方法はありますか?

サファリとアプリの間を行き来するのは本当に避けたいです。任意の提案/ドキュメントをいただければ幸いです。

ありがとうございました、

オスカー

4

5 に答える 5

55

Google からの更新

本日、WebView 経由のサインインを完全にサポートする新しい Google サインイン iOS SDK をリリースしました: developers.google.com/identity/sign-in/ios存在する場合は、後に WebView フォールバックを使用します。いずれの場合も、アプリの拒否を回避するための重要な要素であることがわかっている Safari の切り替えは回避されます。新しい SDK を使用している人々からのフィードバックをお待ちしており、その使用が、その間に人々が実装した (巧妙で勤勉な) 回避策に取って代わることを願っています。


次のメソッドは不要になりました

このメソッドは、カスタム UIWebView を使用して内部ログインを処理します。これは機能し、Apple によって承認されました。

私のアプリは、これが原因でレビューから除外されました

"The app opens a web page in mobile Safari for logging in to Google plus, 
then returns the user to the app. The user should be able log in without opening 
Safari first."

このリンクを参照してくださいhttps://code.google.com/p/google-plus-platform/issues/detail?id=900 次の手順で解決しました

1) openURL をオーバーライドする UIApplication のサブクラスを作成します。

.h

#import <UIKit/UIKit.h>

#define ApplicationOpenGoogleAuthNotification @"ApplicationOpenGoogleAuthNotification"

@interface Application : UIApplication

@end

.m

#import "Application.h"

@implementation Application

- (BOOL)openURL:(NSURL*)url {

    if ([[url absoluteString] hasPrefix:@"googlechrome-x-callback:"]) {

        return NO;

    } else if ([[url absoluteString] hasPrefix:@"https://accounts.google.com/o/oauth2/auth"]) {

        [[NSNotificationCenter defaultCenter] postNotificationName:ApplicationOpenGoogleAuthNotification object:url];
        return NO;

    }

    return [super openURL:url];
}

@end
  • これにより、基本的に、iOS の Chrome から何かを開くことができなくなります。
  • 認証呼び出しをキャッチし、内部 UIWebView にリダイレクトします

2)info.plistに、プリンシパルクラスを追加し、そのためにアプリケーション(またはクラスに名前を付けたもの)

plist キー「NSPrincipalClass」を追加し、値としてメイン アプリケーションのクラス (UIApplication を拡張するクラス、この場合はアプリケーション (上記のコードを参照)) を追加します。

3) 通知を受け取り、内部 Web ビューを開きます

カスタム Application クラスが ApplicationOpenGoogleAuthNotification を送信したら、どこか (おそらく AppDelegate 内) でリッスンし、この通知をキャッチしたら、UIWebView を開きます (通知によって渡された URL を Web ビューの URL として使用します) (私の場合、LoginViewController がリッスンします)この通知を受け取ると、デリゲートに接続された WebView のみを含むビュー コントローラーを開きます)

4) webview 内

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

    if ([[[request URL] absoluteString] hasPrefix:@"com.XXX.XXX:/oauth2callback"]) {
        [GPPURLHandler handleURL:url sourceApplication:@"com.google.chrome.ios"n annotation:nil];

        // Looks like we did log in (onhand of the url), we are logged in, the Google APi handles the rest
        [self.navigationController popViewControllerAnimated:YES];
        return NO;
    }
    return YES;
}
  • または応答を処理する同様のコード
  • 上記のコードの com.XXX.XXX:/oauth2callback を、「com.company.appname:/oauth2callback」のように、会社とアプリの識別子に置き換えます。
  • @"com.apple.mobilesafari" を sourceApplication パラメータとして使用することをお勧めします
于 2014-07-04T15:04:24.047 に答える
12

だから、それはあなたが何をしたいかによって異なります。

Sign-In : これは常に別のアプリケーションを呼び出します。Google+ アプリケーションがインストールされている場合は、それを呼び出します。それ以外の場合は、Chrome と Safari にフォールバックします。

共有/インタラクティブな投稿: 現在、これは常に Chrome または Mobile Safari を使用しています。

友達の取得、アプリのアクティビティの書き込み、プロフィール情報の取得: これらはすべて、サインイン後に取得したアクセス トークンを使用して行われるため、アプリケーションを終了する必要はありません。

サポートされていませんが、SDK をスキップして UIWebView をポップアップし、OAuth リンクを動的に作成してユーザーをそこに送ることができます (SDK に同梱されているオープン ソース ライブラリの GTMOAuth2ViewControllerTouch を参照してください)。以下は、GPPSignIn インスタンスに戻すためにできることの非常に大まかな例です。

ただし、ユーザーがユーザー名とパスワードを入力する必要があることを保証します (おそらく 2 番目の要素)。Google+ アプリを使用すると、すでにサインインしていることがほとんど保証されます。Chrome/Safari ルートを使用すると、ユーザーがすでにサインインしている可能性があります (特に、Google+ サインインで他のアプリを使用している場合)。

これも共有には対応していないため、可能な限り既存の SDK を使用することを強くお勧めします。希望する動作方法について機能リクエストを提出することも良いことです: https://code.google.com/p/google-plus-platform/issues/list

@interface ViewController() {
  GTMOAuth2ViewControllerTouch *controller;
}
@end;

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  GPPSignIn *signIn = [GPPSignIn sharedInstance];
  signIn.clientID = @""; // YOUR CLIENT ID HERE.
  signIn.delegate = self;
}

- (IBAction)didTapSignIn:(id)sender {
  void (^handler)(id, id, id) =
      ^(GTMOAuth2ViewControllerTouch *viewController,
        GTMOAuth2Authentication *auth,
        NSError *error) {
        [self dismissViewControllerAnimated:YES completion:^{
            [controller release];
        }];
        if (error) {
          NSLog(@"%@", error);
          return;
        } else {
          BOOL signedIn = [[GPPSignIn sharedInstance] trySilentAuthentication];
          if(!signedIn) {
            NSLog(@"Sign In failed");
          }
        }
  };
  controller = [[GTMOAuth2ViewControllerTouch
      controllerWithScope:kGTLAuthScopePlusLogin
                 clientID:[GPPSignIn sharedInstance].clientID
             clientSecret:nil
         keychainItemName:[GPPSignIn sharedInstance].keychainName
        completionHandler:handler] retain];
  [self presentViewController:controller animated:YES completion:nil];
}

- (void)finishedWithAuth:(GTMOAuth2Authentication *)auth
                   error:(NSError *)error {
  if (!error) {
    UIAlertView * al = [[UIAlertView alloc] initWithTitle:@"Authorised"
                                                   message:@"Authorised!"
                                                  delegate:nil
                                         cancelButtonTitle:@"OK"
                                         otherButtonTitles:nil];
    [al show];
    [al release];
  }
}

このコードの唯一の本当のトリックは、[GPPSignIn sharedInstance].keychainName を使用することです。これは、GPPSignIn ボタンと同じキーチェーン エントリに認証トークンが格納されることを意味します。これは、[[GPPSignIn sharedInstance] を使用できることを意味します。 trySilentAuthentication] が入力されたら、メイン ライブラリと同じコールバック ベースのフローを維持します。

于 2013-03-08T10:28:06.253 に答える
3

@PeterLapisu アプローチは、Google Plus アプリがインストールされていない場合にうまく機能します。次に、アプリからの発信 URL プレフィックスは次のとおりです。

ただし、Google アプリがインストールされている場合は、発信 URL がもう 1 つあり、プレフィックス リストは次のようになります。

そのため、Google アプリがインストールされている場合、webview を含むアプリ UIViewController と同時に起動されます。その後、ユーザーが Google アプリで正常にログインすると、アプリに戻り、ViewController が表示されます。

この Google アプリを防ぐには、ユーザーのログインを許可し、ユーザーをアプリに戻す必要があります。この議論によると: https://code.google.com/p/google-plus-platform/issues/detail?id=900 Apple によって許可されています。

したがって、私の実装では、まず Google アプリがインストールされているかどうかを確認しています。

- (BOOL)openURL:(NSURL*)url {

NSURL *googlePlusURL = [[NSURL alloc] initWithString:@"gplus://plus.google.com/"];

BOOL hasGPPlusAppInstalled = [[UIApplication sharedApplication] canOpenURL:googlePlusURL];


if(!hasGPPlusAppInstalled)
{
    if ([[url absoluteString] hasPrefix:@"googlechrome-x-callback:"]) {

        return NO;

    } else if ([[url absoluteString] hasPrefix:@"https://accounts.google.com/o/oauth2/auth"]) {

        [[NSNotificationCenter defaultCenter] postNotificationName:ApplicationOpenGoogleAuthNotification object:url];
        return NO;

    }
}


return [super openURL:url];
}

編集:

これで、私のアプリがこのソリューションで最終的に承認されたことを確認できます。

于 2015-02-28T21:39:43.143 に答える
0

(新しい) Google サインイン iOS SDKを使用します。

サインイン プロセスを完了するための Google アプリが存在しない場合、SDK は WebView を介したサインインをネイティブにサポートします。この目的のために、複数の Google アプリへの潜在的なディスパッチもサポートしています。

于 2015-05-29T06:17:01.763 に答える