{"id":20294200,"url":"https://github.com/grab/grabplatform-sdk-ios","last_synced_at":"2025-04-11T11:42:50.942Z","repository":{"id":97825896,"uuid":"157847499","full_name":"grab/grabplatform-sdk-ios","owner":"grab","description":"GrabPlatform SDK for iOS","archived":false,"fork":false,"pushed_at":"2021-06-14T04:50:17.000Z","size":193,"stargazers_count":13,"open_issues_count":1,"forks_count":2,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-25T08:03:19.444Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://developer.grab.com","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-16T09:53:29.000Z","updated_at":"2025-03-23T13:37:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"9f1ed030-df6b-4923-81b0-4eb5fcdb6353","html_url":"https://github.com/grab/grabplatform-sdk-ios","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grab%2Fgrabplatform-sdk-ios","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grab%2Fgrabplatform-sdk-ios/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grab%2Fgrabplatform-sdk-ios/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grab%2Fgrabplatform-sdk-ios/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grab","download_url":"https://codeload.github.com/grab/grabplatform-sdk-ios/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248385968,"owners_count":21094982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T15:28:12.355Z","updated_at":"2025-04-11T11:42:50.932Z","avatar_url":"https://github.com/grab.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GrabID Partner SDK - iOS\n\nThe GrabId Partner SDK allows users to sign in with their Grab account from third-party apps.\n\nPlease visit [our developer site](https://developers.grab.com) for integration instructions, documentation, support information, \nand terms of service.\n\n[![Version](https://img.shields.io/cocoapods/v/GrabIdPartnerSDK.svg?style=flat)](https://cocoapods.org/pods/GrabIdPartnerSDK)\n[![License](https://img.shields.io/cocoapods/l/GrabIdPartnerSDK.svg?style=flat)](https://cocoapods.org/pods/GrabIdPartnerSDK)\n[![Platform](https://img.shields.io/cocoapods/p/GrabIdPartnerSDK.svg?style=flat)](https://cocoapods.org/pods/GrabIdPartnerSDK)\n\n## Release Notes - 1.0.5\n\nAllow app to change redirectUrl, scope, hint, idTokenHint and prompt in LoginSession.\n\n## Release Notes - 1.0.4\n\nLogin with PAX now supports non Grab domain for the authorization url. PAX has updated the scheme to grabconnect2. Partner wants to use\ncustom authorization domain (non default Grab domain) must:\n1. Register with Grab ID team to use grabconnect2 URL scheme to deeplink to PAX.\n2. The custom domain must be whitelist by the Grab ID mobile team. \n3. Add grabconnect2 to their application's info.plist (SDK example has been updated to grabconnect2). Please verify the grabconnect2 scheme  matches \nyour registration with the Grab ID team.\n\n## Release Notes - 1.0.3\nThe login API supports \"Single Sign-On.\" Partner application can configure with Grab Id to take advantage of the login state of the Grab applications\n(i.e. PAX, etc.) for authorization. The client_public_info_endpoint contained in response of the discovery URL will provide the configuration of the URL \nscheme of the application that can be used to authenticate the user on behalf of partner application.  If the user already login to the application \n(i.e. Grab PAX application, etc.), the user will only need to provide consent instead of going through the cumbersome authentication process. The login \nAPI will proxy the authorization request to the application (e.g. Grab PAX application) instead of using default Grab web login flow to authorize the user. \nPartner can also configure with Grab Id to launch into the  app store instead when it is not desirable to default authorization to web login. In this case, \npartner must handle error to retry or cancel the authorization request. \n   \n## Release Notes - 1.0.2\n\n- Partner SDK will login with PAX or DAX app instead of using webview if PAX/DAX is installed\n- Consumers need to update their `.plist` file with a new `LSApplicationQueriesSchemes` called `grabconnect`\n\n## Example\n\nTo run the example project, clone the repo, and run `pod install` from the Example directory first.\n\n## Requirements\n- iOS 9.0+\n- Xcode 9.0+\n- Swift 3.2 / 4.1+\n- Objective-C\n\n## Analytics\n\nGrabID Partner SDK does not send any analytic data due to user privacy. Third-party is responsible for their own analytics to troubleshoot error and\nanalytics data to address their analytics requirements.\n\n## Installation the GrabID Partner SDK\n\nIn final version, SDK might be hosted as a private pod so that you can use something like: `pod 'GrabIdPartnerSDK'`\n\nFor this mock version, please copy/drag the framework to this project. While coping the framework in Project Explorer, check “Copy items if needed”.\n\nSelect the Project, Choose Target → Project Name → Select General → Scroll to “Embedded Binaries”. Press “+” and Add the framework.\n\nIf there are multiple Framework with same name in “Linked Frameworks and Libraries”, delete other ones, and just keep only one.\n\nAlternatively, the following command can be used in Podfile\n\n```swift\npod 'GrabIdPartnerSDK', :git =\u003e 'https://github.com/grab/grabplatform-sdk-ios.git', :tag =\u003e '1.0.1'\n```\n\n## Getting Started\n\n### SDK Configuration\nFirstly, you need to register an application to Grab and get credentials for your app from GrabID team.\n\nThen, configure your project with information for the GrabId Partner SDK. Right-click Info.plist file and select Open As -\u003e Source Code.\f\nAdd the following snippet, replacing the placeholders within the square brackets (`[]`):\n\n### Setup URLScheme to handle redirect URL\n```swift\n\u003ckey\u003eCFBundleURLTypes\u003c/key\u003e\n\u003carray\u003e\n\u003cdict\u003e\n\u003ckey\u003eCFBundleURLSchemes\u003c/key\u003e\n\u003carray\u003e\n\u003cstring\u003egrab[PartnerID]\u003c/string\u003e\n\u003c/array\u003e\n\u003c/dict\u003e\n\u003c/array\u003e\n\u003ckey\u003eGrabPartnerID\u003c/key\u003e\n\u003cstring\u003e[PartnerID]\u003c/string\u003e\n\u003c/dict\u003e\n```\n### Example\n\n```swift\n\u003ckey\u003eCFBundleURLTypes\u003c/key\u003e\n\u003carray\u003e\n\u003cdict\u003e\n\u003ckey\u003eCFBundleTypeRole\u003c/key\u003e\n\u003cstring\u003eEditor\u003c/string\u003e\n\u003ckey\u003eCFBundleURLName\u003c/key\u003e\n\u003cstring\u003ecom.grab.grabweblogin\u003c/string\u003e\n\u003ckey\u003eCFBundleURLSchemes\u003c/key\u003e\n\u003carray\u003e\n\u003cstring\u003egrabweblogin\u003c/string\u003e\n\u003c/array\u003e\n\u003c/dict\u003e\n\u003c/array\u003e\n```\n\n### Configure GrabId Partner SDK to login with Grab (Optional, see Create LoginSession)\n\nPartner application should register their RedirectUrl and obtain the Client Id, Scope, and Service Discovery end point from the Grab Id team.\n\n```swift\n\u003ckey\u003eGrabIdPartnerSDK\u003c/key\u003e\n\u003cdict\u003e\n\u003ckey\u003eClientId\u003c/key\u003e\n\u003cstring\u003e[client id]\u003c/string\u003e\n\u003ckey\u003eRedirectUrl\u003c/key\u003e\n\u003cstring\u003egrab[PartnerID]://[Partner-Redirect-Uri-Path]\u003c/string\u003e\n\u003ckey\u003eScope\u003c/key\u003e\n\u003cstring\u003e[Permission scope] [Permission scope] [Permission scope] openid\u003c/string\u003e\n\u003ckey\u003eServiceDiscoveryUrl\u003c/key\u003e\n\u003cstring\u003e[obtain the service discovery endpoint from the GrabId team]\u003c/string\u003e\n\u003c-- Optional\n\u003ckey\u003eHint\u003c/key\u003e\n\u003cstring\u003e[Hint - set the query parameter login hint for the Authorize end point. Login hint contains prefilled user information in JWT format.]\u003c/string\u003e\n\n\u003ckey\u003eIdTokenHint\u003c/key\u003e\n\u003cstring\u003e[IdTokenHint - set the query parameter id_token_hint for the Authorize end point. Id token hint can be used for single sign in.]\u003c/string\u003e\n\n\u003ckey\u003ePrompt\u003c/key\u003e\n\u003cstring\u003e[Prompt - set the option to prompt the user, please refer to Grab ID authenticate service documentation]\u003c/string\u003e\n\n\u003ckey\u003eRequest\u003c/key\u003e\n\u003cstring\u003e[Pass thru string if specified will add query parameter \u0026request=[request string] to the /authorize service call]\u003c/string\u003e\n\n\u003c-- AcrValues if specified will add query parameter \"\u0026acr_values=[key]:[value] [key]:[value] ...\" to the /authorize service call. \n    e.g. \"\u0026acr_values=SERVICE:PASSENGER consent_ctx:countryCode=SG\" --\u003e\n\u003cdict\u003eAcrValues\n\u003ckey\u003e[e.g. SERVICE, consent_ctx, etc.]\u003c/key\u003e\n\u003cstring\u003e[e.g. PASSENGER, countryCode=SG, etc.]\u003c/String\u003e\n\u003c/dict\u003e\n--\u003e\n\n\u003c-- For testing only. This test resource is used by the Grab Id Example\n\u003ckey\u003eTestProtectedResourceUrl\u003c/key\u003e\n\u003cstring\u003ereplace with test resource url\u003c/string\u003e\n--\u003e\n\n\u003c/dict\u003e\n```\n### Example\n\nValues provided here are example only. ClientId, ServiceDiscoveryUrl, and TestProtectedResourceUrl are provided for example only. They will not work\nwith the Example provided. Please obtain the information if you are interested in running the test app.\n```swift\n\u003ckey\u003eGrabPartnerIdSDK\u003c/key\u003e\n\u003cdict\u003e\n\u003ckey\u003eClientId\u003c/key\u003e\n\u003cstring\u003ee20e3567-3fa3-4b13-a135-b00fd88e3295\u003c/string\u003e\n\u003ckey\u003eHint\u003c/key\u003e\n\u003cstring\u003eOxy0dKP4RLbGdksH\u003c/string\u003e\n\u003ckey\u003eRedirectUrl\u003c/key\u003e\n\u003cstring\u003egrabweblogin://open\u003c/string\u003e\n\u003ckey\u003eScope\u003c/key\u003e\n\u003cstring\u003egid_test_scope_1 gid_test_scope_2 gid_test_scope_3 openid\u003c/string\u003e\n\u003ckey\u003eServiceDiscoveryUrl\u003c/key\u003e\n\u003cstring\u003ehttps://api.grabidpartner.com/authorize\u003c/string\u003e\n\u003ckey\u003eTestProtectedResourceUrl\u003c/key\u003e\n\u003cstring\u003ehttps://api.grabidpartner.com/testresource\u003c/string\u003e\n\u003c/dict\u003e\n```\n\n### Access the GrabId Partner SDK APIs\n\nObtain a share instance of the GrabIdPartner\n```swift\nguard let grabIdPartner = GrabIdPartner.sharedInstance() else {\n  // handle failure to get an instance of the GrabIdPartner\n  return\n}\n```\n\n### Login with GrabId service\n\n#### Using the loadLoginSession API to get configurations in the Info plist\n```swift\nfunc signInWithLoginConfig() {\n  guard let grabIdPartner = GrabIdPartner.sharedInstance() else {\n    // handle failure to instantiate GrabIdPartner\n    return\n  }\n  grabIdPartner.loadLoginSession() { [weak self] (loginSession, error) in\n    guard let self = self else {\n      return\n    }\n    self.loginSession = loginSession\n    if let error = error {\n      // handle failure to load LoginSession configurations\n    } else {\n      // proceed to login\n      grabIdPartner.login(loginSession: loginSession, \n        presentingViewController: [Partner App View]) { [weak self] (error) in\n        guard let self = self else {\n          return\n        }\n      }\n    }\n  }\n}\n```\n\n#### Using LoginSession\n```swift\nfunc signIn() {\n  guard let grabIdPartner = GrabIdPartner.sharedInstance() else {\n    // handle failure to instantiate GrabIdPartner\n    return\n  }\n  let url = URL(string:Configuration.redirectUri)\n  if let redirectUrl = url {\n    loginSession = LoginSession(clientId: \"[Partner Client Id]\" , \n                                redirectUrl: \"[Partner Redirect URL]\", \n                                scope: \"\u003cscope\u003e\"\n                                serviceDiscoveryUrl: \"\u003cobtain the service disocvery endpoints from GrabId Service team\u003e\",\n                                hint:\" \u003clogin hint for the Authorize end point. Login hint contains prefilled user information in JWT format.\u003e\"\n                                idTokenHint: \"\u003cid_token_hint for the Authorize end point. Id token hint can be used for single sign in.\"\u003e\n                                prompt: \"\u003cset the option to prompt the user, please refer to Grab ID authenticate service documentation\u003e\")\n    grabIdPartner.login(loginSession: loginSession, \n                      presentingViewController: \u003cpartner app view\u003e) { [weak self] (error) in\n      guard let self = self else {\n        return\n      }\n    }\n  }\n}\n```\n\n### Handling URL redirect after user authenticate with Web login\n\nThe login API will trigger the Grab Id in-app web authorization. After the user successfully authenticate and give consent to the partner application access, Grab Id service will validate the redirect URL and the security attributes in the query parameters.  If the redirect URL is registered with Grab Id service, Grab Id service will send the redirect URL to the browser (see \"Setup URLScheme for partner application to handle redirect URL\")  and partner application  will receive the redirect URL with an authorization code, state, and error (if any) in the query parameters.  \n\n#### Connect App Delegate\n\nPartner application needs to implement a method in their AppDelegate class for the app to respond when their application is launched via the custom URL scheme:\n\n\n### AppDelegate.swift \n\n```swift\nimport GrabIdPartnerSDK\n\nfunc application(_ app: UIApplication, \n                  open url: URL, \n                  options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -\u003e Bool {\n  guard let grabIdPartner = GrabIdPartner.sharedInstance() else {\n    // handle failure to instantiate GrabIdPartner\n    return\n  }\n\n  ...\n\n  // Partner application must provide the same  loginSession created during login.  \n  grabIdPartner.exchangeToken(loginSession: loginSession, url: url) { [weak self] (error) \n    guard let self = self else {\n      return\n    }\n\n    // Complete the web login flow, close the web browser, etc.\n    if !grabIdPartner.loginCompleted(loginSession: loginSession) {\n      // handle login completion error (i.e. dismiss the web login view)\n      ...\n    }       \n    guard error != nil else {\n      // handle login error\n      return\n    }\n\n    // login is successful and LoginSession now contains the access token, id token, etc.\n  }\n}\n```\n### Get Id Token Information\n\nPartner application can get information about the id token using the getIdTokenInfo API:\n\n```swift\ngrabIdPartner.getIdTokenInfo(loginSession: loginSession) { [weak self] (idTokenInfo, error) in \n  guard let self = self else {\n    return\n  }\n}\n```\n\nIdToken contains information about the valid time of the token, partner id, partner user id, nonce, issuer, etc\n\n### Check if token is valid\n\n#### Access Token\n\nApplication can use the isValidAccessToken API to check if the access token is valid\n\n```swift\nlet isValid = grabIdPartner.isValidAccessToken(loginSession: loginSession)\n```\n\n#### Id Token\n\nApplication can use the isValidIdToken API to check if the access token is valid\n```swift\nlet isValid = grabIdPartner.isValidIdToken(idTokenInfo: idTokenInfo)\n```\n\n### Logout \n\nPartner application can logout using the logout API. Currently logout removes cached LoginSession and IdTokenInfo from the keychain and user defaults. It does not support revoking the tokens from Grab Id service. Revoking authorization will be supported in future release.   \n\n```swift\ngrabIdPartner.logout(loginSession: loginSession) { [weak self] (error) in \n  guard let self = self else {\n    return\n  }\n}\n```\n\n## GrabId Partner SDK API\n\n### LoginSession\n```swift\nclientId: String                            Application registered client id.\n\nredirectUrl: URL                            The redirect URL that was used in the initial authorization request.\n                                            This URL must register with Grab Id service during Partner registration.\n\nscope: String                               Specify the requested permission scopes.\n\nrequest: String                             Partner specific request string.\n\nhint: String                                Serialized JWT token that client already has, if provided, the user will \nnot be prompted to authenticate\n\nacrValues: [String:String]                  Partner specific acr values (name value pairs).\n\nserviceDiscoveryUrl : String                Service discovery Url (please obtain this endpoint from GrabId service team)\n\nREAD ONLY PROPERTIES\n\ncode: String?                               Unique authorization code (from query parameter in the redirect url). \n                                            This code will be used by the exchangeToken API to obtain the accessToken \n                                            and idToken.\n\ncodeVerifier: String?                       The code verifier for the PKCE request, that is generated by the login API \n                                            before the authorization request.\n\naccessTokenExpiresAt: Date?                 Access token expiration date.\n\nstate: String?                              The login API generates a unique state paramter during authorization, the\n                                            Grab Id service will include the state parameter in the query parameter \n                                            in the redirect URL to mitigate CSRF attacks.\n\ntokenType: String?                          Indicates the grant type of this token request.\n\nnonce: String?                              Unique token generated during login.\n\naccessToken: String?                        Access token to make Grab API requests on behalf of the user.\n\nidToken: String?                            JWT contains user profile information (Signed).\n\nrefreshToken: String?                       Used to obtain/renewed access token (current not supported).\n```\n\n### IdTokenInfo\n\n```swift\naudience: String?                    Intended recipient of the token.\nservice: String?                     Service (i.e. PASSENGER).\n\nnotValidBefore: Date?                Id token validation start time.\n\nexpiration: Date?                    Id token expiration date.             \n\nissuer: String?                      Issuer (i.e. \"https://testissuer.grab.com).\n\ntokenId: String?                     Id Token (Unsigned).\n\npartnerId: String?                   Partner Id.\n\npartnerUserId: String?               Partner User id\n\nnonce: String?                       Unique token generated during login. The value should match the \n                                     nonce in the LoginSession.\n```\n\n### GrabIdPartnerProtocol\n```swift\nsharedInstance() : GrabIdPartnerProtocol\n\nStatic function to get a shared instance of GrabIdPartner to access the Grab Id Partner SDK APIs.\n\nReturn\n  GrabIdPartnerProtocol \n```\n\n```swift\nloadLoginSession(completion: @escaping(LoginSession?, GrabIdPartnerError?)) : Void\n\nRead the ClientId, Scope, Hint, RedirectUrl, serviceDiscoveryUrl, Request (optional), AcrValues (optional) from  the application's info plist and create a LoginSession. Please obtain the serviceDiscoveryDiscoveryUrl production and staging endpoints from the Grab Id team.\n\nCompletion Handler\n  Receives a LoginSession with nil error if the information in the plist is valid, Otherwise the \n  completion handler will be called with nil LoginSession and a GrabIdPartnerError.\n```\n\n```swift\nlogin(loginSession: LoginSession, \n      presentingViewController: UIViewController, completion: @escaping(GrabIdPartnerError?)) : Void\n\nThe login API will attempt to set up the LoginSession with cached LoginSession data. Currently refresh token is not supported. First, the login API will get the Grab Id service end points (i.e. token, token info) from Grab Id discovery service (see configuration above) and generates an unique code verifier, nonce, state as security attributes. The security attributes, redirect URL, request string, and acr values are inlcuded in the query parameters to create the Grab Id authorize service URL.  \n\nGrab Id partner app has the option to configure their application to sign in through Grab Passenger App by registering or contact Grab developer support to activate this feature. This feature will allow users to take advantage of Grab login state to bypass the Web login experience with needing to validate with OTP. Authenticate will be handled in Grab Passenger App and the user only needs to consent access without going through the OTP validation. This only applies to Grab SDK Partner that has registered with Grab ID to use the Login with Grab Passenger application feature. Grab Partner app will need to add:\n\n```\n\u003ckey\u003eLSApplicationQueriesSchemes\u003c/key\u003e\n\u003carray\u003e\n\u003cstring\u003egrab\u003c/string\u003e\n\u003cstring\u003egrabconnect2\u003c/string\u003e\n\u003c/array\u003e\n```\nto the application info.plist to let the Grab ID Partner SDK to query for Grab Passenger Application that can handle Login in with Grab Application feature.\n\nThere are several conditions that must be met before the Grab ID SDK uses for the Login with Grab Passenger Application. Otherwise, it will revert back to the existing web login flow:\n1. Partner app loginSession or login call cannot contain hint, id_token_hint, or prompt. Partner providing any of this parameter either has the ability to take advantage of the login token (i.e. providing hint or id_token_hint or explicitly wants to control the login flow (i.e. prompt user for additional information).\n2. By default, all new Partner apps will opt-in to use the Login with Grab Passenger Application feature. If the Partner app failed to add the grabconnect2 scheme to LSApplicationQueriesSchemes in info.plist. Grab ID SDK will not be able to determine if the Grab Passenger app has implemented Login with Grab Passenger app feature and will have to revert to the web login flow.\n3. Existing partner app that uses the Grab ID SDK will need to update the SDK and add the grabconnect2 scheme to LSApplicationQueriesSchemes in info.plist to take advantage of this feature.\n4. Grab Passenger App is updated to contain the Login with Grab Passenger app feature.\n\nIf Grab Id SDK cannot use the Login with Grab Passenger App feature (see conditions above), then the login API will present the SFSafariViewController and navigate to the Grab Id authorize URL for in-app web authorization. Once the user finished logging in. Grab Id authorize service will redirect back to the app with the redirect url that includes the authorization code, state, and error (if any). Application must handle the URL redirect (see \"Handling URL redirect after user authenticate with Web login\")\n\nNote:\n\npresentingViewController is used in case that SFSafariViewController will be presented on top of it when logging in with webpage.\n\nCompletion Handler\n  nil if no error, GrabIdPartnerErroir with error code and message otherwise.\n```\n\n```swift\nexchangeToken(loginSession: LoginSession, url: URL, completion: @escaping (GrabIdPartnerError?)) : Void\n\nThe exchangeToken API is called when AppDelegates's handleOpenUrl is called to handle redirect after the in-app web authorization. Application should forward the redirect url to the exchangeToken API. The exchangeToken API will check for redirect error, validate the state in the query parameter against the state in the loginSession.  It will send the authorization code to Grab Id token service to get access token, id token, and access token expiration information. The tokens will be saved in the keychain and LoginSession will be saved in user defaults. The exchangeToken API will call loginCompleted internally to dismiss the SFSafariViewContoller that was displayed in login for the in-app web authorization flow.\n\nCompletion Handler\n  nil if no error, GrabIdPartnerErroir with error code and message otherwise.\n\n```\n\n```swift\nloginCompleted(loginSession: LoginSession) : Bool\n\nApplication that handles their own redirect without calling the exchangeToken API must call the loginCompleted API. This  API is required to complete the in-app web authorization flow. It is the only way to dismiss the SFSafariViewController.\n\nReturn\n  Return true if it is successful in dismissing the web login flow, false otherwise. \n\n```\n\n```swift\nlogout(loginSession: LoginSession, completion: ((GrabIdPartnerError?)) : Void\n\nThe logout API will remove cached loginSession and related idTokenInfo.  Calling login after logout or with an expired access token will trigger the in-app web authorization flow. Revoke token support will be added in future release.\n\nCompletion Handler\n  nil if no error, GrabIdPartnerErroir with error code and message otherwise.\n\n```\n\n```swift\ngetIdTokenInfo(loginSession: LoginSession, completion: @escaping (IdTokenInfo?, GrabIdPartnerError?))-\u003e Void\n\nApplication can call the getIdTokenInfo API to get the idToken information (i.e. id token expiration date, unsigned Id token, nonce,  audience , partner user id, partner id, etc.). It caches the id token in the key chain and the rest of the Id token information are stored in user defaults. getIdTokenInfo will return IdTokenInfo from cache if the Id token has not expired. getIdTokenInfo API will return error if the Id Token has expired. Application must call the login API to get a new Id Token before calling getIdTokenInfo API to get the IdTokenInfo/\n\nCompletion Handler\n  If there is no error, idTokenInfo contains id token information, otherwise idTokenInfo will be nil\n  If there is error, idTokenInfo will be nil and GrabIdPartnerError will contain the error code and message.\n```\n\n```swift\nisValidAccessToken(loginSession: LoginSession) -\u003e Bool\n\nDetermine if the access token in the LoginSession is valid (using the access token expiration date).\n\nReturn\n  true if the access token is valid, false otherwise\n```\n\n```swift\nisValidIdToken(idToken: IdTokenInfo) -\u003e Bool\n\nDetermine id token in IdTokenInfo is valid (using the id token start time and expiration date).\n\nReturn\n  true if the id token is valid, false otherwise\n```\n\n### Grab Id SDK Error\n\n#### GrabIdPartnerError\n```swift\ndomain: GrabIdPartnerErrorDomain?   Source of the error\ncode : GrabIdPartnerErrorCode       Error code\nlocalizeMessage : String?           Error message\nserviceError : Error?               System Error\n```\n##### GrabIdPartnerErrorDomain\n```swift\nserviceDiscovery\nloadConfiguration\nauthorization\nexchangeToken\ngetIdTokenInfo\nlogout\ncustomProtocolsService\n\n```\n##### GrabIdPartnerErrorCode\n```swift\ngrabIdServiceFailed\ndiscoveryServiceFailed\nidTokenInfoServiceFailed\nexchangeTokenServiceFailed\nauthorizationInitializationFailure\nsecurityValidationFailed\nlogoutFailed\ninvalidIdToken \ninvalidNonce\ninvalidConfiguration       \nsomethingWentWrong           \nnetwork                      \ninvalidClientId               \ninvalidScope               \ninvalidRedirectUrl        \ninvalidAuthorizationCode     \ninvalidUrl                     \ninvalidPartnerId           \nunAuthorized                 \nauthorizationFailed         \nserviceUnavailable             \nserviceError                  \ninvalidAccessToken             \ninvalidResponse                \ninvalidServiceDiscoveryUrl\ninvalidAppBundle\ninvalidCustomProtocolUrl\nfailedTolaunchAppStoreLink     // Failed to launch the configured app store link\nlaunchAppStoreLink             // Launch the configured app store link\n\n  \npartnerAppError = 10000        Application defined errors are 10000 and above\n```\n## Objective-C Support\n\nFor example in using Grab Id Partner SDK with Objective-C. Please follow example in GrabIdPartnerSDKTests-Objc.m in Tests. \n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrab%2Fgrabplatform-sdk-ios","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrab%2Fgrabplatform-sdk-ios","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrab%2Fgrabplatform-sdk-ios/lists"}