يؤدي استخدام ميزة "قلب التطبيقات" (App Flip) المستنِد إلى بروتوكول OAuth إلى فتح تطبيق iOS من أحد تطبيقات Google. لمساعدة مستخدم تطبيق Google على ربط حسابه بسهولة أكبر. عليك إجراء تغييرات طفيفة على رمز تطبيق iOS لتنفيذ هذه الميزة.
ستتعرّف في هذا المستند على كيفية تعديل تطبيق iOS لدعم ميزة App Flip.
تجربة النموذج
نموذج تطبيق ميزة "قلب التطبيق" تعرض عملية دمج لربط الحساب على نظام iOS يتوافق مع App Flip. يمكنك استخدام هذا التطبيق للتحقّق من طريقة الردّ على رسالة App Flip واردة عامة. من تطبيقات الأجهزة الجوّالة من Google.
تم ضبط نموذج التطبيق مسبقًا للدمج مع أداة اختبار قلب التطبيق). iOS، الذي يمكنك استخدامه للتحقّق من تكامل تطبيق iOS مع ميزة App Flip قبل يمكنك إعداد ربط الحساب بـ Google. يحاكي هذا التطبيق الرابط العام. يتم تشغيلها بواسطة تطبيقات Google المتوافقة مع الأجهزة الجوّالة عند تفعيل ميزة "قلب التطبيقات".
آلية العمل
في ما يلي خطوات العملية التي يتّخذها تطبيق Google وتطبيقك عند يحدث قلب التطبيق:
يحاول تطبيق Google فتح الرابط العام لتطبيقك. من الممكن افتح التطبيق إذا كان مثبّتًا على جهاز المستخدم ومرتبطًا الرابط العام. راجِع إتاحة الروابط العامة لمعرفة التفاصيل.
يتحقّق تطبيقك من ترميز المَعلمتَين
client_id
وredirect_uri
. في عنوان URL الوارد مع الرابط العام المتوقع لـ Google.يطلب تطبيقك رمز تفويض من خادم OAuth2. في النهاية يعرض التطبيق رمز تفويض أو خطأ تطبيق Google. وللقيام بذلك، يتم فتح رابط Google العام مع ملحق المَعلمات لرمز التفويض أو الخطأ.
يعالج تطبيق Google الرابط العام الوارد من Google ويستمر في بقية التدفق. إذا تم تقديم رمز تفويض، سيتم على الفور. يحدث تبادل الرموز المميزة بين الخوادم، بالطريقة نفسها وهو ما يحدث في تدفق ربط OAuth المستند إلى المتصفح. إذا كان رمز الخطأ يستمر تدفق الربط مع الخيارات البديلة.
تعديل تطبيق iOS لدعم ميزة "قلب التطبيقات"
لإتاحة ميزة "قلب التطبيقات"، عليك إجراء التغييرات التالية على الرمز في تطبيق iOS:
- استخدِم الاسم المعرِّف "
NSUserActivityTypeBrowsingWeb
" في ميزة "تفويض التطبيقات". - التقاط المَعلمتَين
redirect_uri
وstate
من عنوان URL لاستخدامهما لاحقًا - تأكَّد من تطابق
redirect_uri
مع هذا التنسيق:https://oauth-redirect.googleusercontent.com/a/GOOGLE_APP_BUNDLE_ID https://oauth-redirect-sandbox.googleusercontent.com/a/GOOGLE_APP_BUNDLE_ID
تحقَّق من تطابُق معرِّف العميل مع القيمة المتوقَّعة. استخدِم ما يلي: نموذج التعليمات البرمجية:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let incomingURL = userActivity.webpageURL, let components = URLComponents(url: incomingURL, resolvingAgainstBaseURL: false), let params = components.queryItems else { return false } if let clientId = params.filter({$0.name == "client_id"}).first?.value, let state = params.filter({$0.name == "state"}).first?.value, let redirectUri = params.filter({$0.name == "redirect_uri"}).first?.value { // Save the redirect_uri and state for later... // Verify the client id return (clientId == GOOGLE_CLIENT_ID) } else { // Missing required parameters return false } }
بعد نجاح التفويض، اطلب معرّف الموارد المنتظم (URI) لإعادة التوجيه مع الحصول على الإذن الرمز. استخدِم نموذج الرمز البرمجي التالي:
func returnAuthCode(code: String, state: String, redirectUri: String) { var redirectURL = URL(string: redirectUri) var components = URLComponents(url: redirectURL, resolvingAgainstBaseURL: false) // Return the authorization code and original state let paramAuthCode = URLQueryItem(name: "code", value: code) let paramState = URLQueryItem(name: "state", value: state) components?.queryItems = [paramAuthCode, paramState] if let resultURL = components?.url { UIApplication.shared.open( resultURL, options: [UIApplicationOpenURLOptionUniversalLinksOnly : true], completionHandler: nil) } }
إذا حدث خطأ، أرفِق نتيجة خطأ بمعرّف الموارد المنتظم (URI) لإعادة التوجيه بدلاً من ذلك. استخدِم نموذج الرمز البرمجي التالي:
func returnError(redirectUri: String) { var redirectURL = URL(string: redirectUri) var components = URLComponents(url: redirectURL, resolvingAgainstBaseURL: false) // Return the authorization code and original state let paramError = URLQueryItem(name: "error", value: "invalid_request") let paramDescription = URLQueryItem(name: "error_description", value: "Invalid Request") components?.queryItems = [paramError, paramDescription] if let resultURL = components?.url { UIApplication.shared.open( resultURL, options: [UIApplicationOpenURLOptionUniversalLinksOnly : true], completionHandler: nil) } }
مَعلمات طلب البحث للرابط العام لتطبيقك
عند فتح هذا التطبيق من خلال تطبيق Google، يتضمّن الرابط العام لتطبيقك ما يلي: مَعلمات طلب البحث:
client_id
(String
): Googleclient_id
المسجَّل ضمن تطبيقك.scope
(List of String
): قائمة بالنطاقات المفصولة بمسافات مطلوبةstate
(String
): رقم تعريف غير تستخدمه Google للتحقّق من أنّ التفويض هي استجابة لطلب Google الصادر.redirect_uri
(String
): رابط Google العام. "قلب" معرّف الموارد المنتظم (URI) المطلوب فتحه تطبيق Google واجتياز النتائج
مَعلمات طلب البحث لرابط Google العام
المَعلمات المستخدَمة عند عرض نتيجة التفويض بنجاح:
code
(String
): قيمة رمز التفويض، في حال توفّرها.state
(String
): القيمة الدقيقة التي يتم تلقّيها من الرابط العام الوارد
المَعلمات التي يتم استخدامها عند عرض نتيجة التفويض بشكل غير ناجح:
error
(String
)، مع القيم التالية:cancelled
: خطأ يمكن إصلاحه. سيحاول تطبيق Google استخدام الحساب باستخدام عنوان URL للتفويض. بعض الأمثلة هي فشل المستخدم لتسجيل الدخول، أو عدم اتصال الجهاز بالإنترنت أو انتهاء مهلة الاتصال.unrecoverable
: خطأ غير قابل للإصلاح. على سبيل المثال، يحاول المستخدم الربط بحساب غير مفعَّل.سيلغي تطبيق Google ربط الحساب.invalid_request
: معلَمات الطلب غير صالحة أو غير متوفّرة يمكن إصلاح هذا الخطأ. سيحاول تطبيق Google ربط الحسابات باستخدام عنوان URL للتفويض.access_denied
: يرفض المستخدم طلب الموافقة. هذا خطأ لا يمكن إصلاحه؛ يلغي تطبيق Google الربط.
error_description
(String
، اختياري): رسالة خطأ سهلة الاستخدام
بالنسبة إلى جميع أنواع الأخطاء، يجب عرض بيانات الاستجابة على
REDIRECT_URI
للتأكّد من ترتيب الإجراء الاحتياطي المناسب.
تعديل نقطة نهاية التفويض لإتاحة استخدام ميزة "قلب التطبيقات"
يمكنك ضبط النظام الأساسي لقبول الطلبات باستخدام عناوين URL لإعادة التوجيه لميزة App Flip من Google:
- تطبيق Google Home
https://oauth-redirect.googleusercontent.com/a/com.google.Chromecast.dev https://oauth-redirect.googleusercontent.com/a/com.google.Chromecast.enterprise https://oauth-redirect.googleusercontent.com/a/com.google.Chromecast https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.Chromecast.dev https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.Chromecast.enterprise https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.Chromecast
- تطبيق "مساعد Google"
https://oauth-redirect.googleusercontent.com/a/com.google.OPA.dev https://oauth-redirect.googleusercontent.com/a/com.google.OPA.enterprise https://oauth-redirect.googleusercontent.com/a/com.google.OPA https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.OPA.dev https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.OPA.enterprise https://oauth-redirect-sandbox.googleusercontent.com/a/com.google.OPA
تأكّد من أنّ client_id
وعنوان URL المحدَّدين من خلال المَعلمة redirect_uri
تتطابق مع القيم المتوقعة عند تلقي طلب. إذا كانت عملية التحقّق من العميل
الأخطاء، يمكنك إرجاع الخطأ invalid_request
إلى redirect_uri
.