iOS Civic App Connect
Civic App Connect 是一个库,允许第三方连接到 Civic Secure Identity iOS 应用。
简介
此库允许您使用集成门户 API 连接到 Civic Secure Identity iOS 应用。为了使用此库,您需要在 集成门户 上注册。注册后,您可以提供必要的信息以允许库将您的 iOS 应用程序连接到 Civic Secure Identity iOS 应用。此库还提供了一个可以根据需要定制的 Civic 风格按钮,或者你可以根据应用程序的需要以任何适当的方式启动流程。
要求
- iOS 8.0+
- Xcode 10+
- Swift 4+
安装
Cocoapods
Civic App Connect 可以通过 CocoaPods 获取。要安装它,只需将以下行添加到您的 Podfile 中
pod 'CivicConnect'
Carthage
要使用 Carthage 将 Civic App Connect 整合到您的 Xcode 项目中,请在您的 Cartfile
中指定它
github "civicteam/civic-connect-ios-public"
运行 carthage update
构建框架,并将构建的 CivicConnect.framework 拖入您的 Xcode 项目。
入门指南
示例应用
要运行示例项目,请克隆存储库,然后运行 pod install
命令。使用 Xcode 打开 CivicConnect.xcworkspace
,在 Info.plist
中您需要提供 CivicApplicationIdentifier
和 CivicSecret
,然后运行 CivicConnect-Example
模式。样本项目包含文档化的代码,说明如何使用此库。
使用方法
此库支持 Objective-C 和 Swift,因此每个代码片段将包含相应的 Objective-C 和 Swift 部分。
初始化
在使用库之前,您需要使用正确的字段初始化它。这些值可以在您注册应用程序时在集成门户找到。初始化库需要以下字段:
名称 | 必需 | 描述 |
---|---|---|
应用程序标识符 | 是 | 用于识别第三方。 |
移动应用程序标识符 | 是 | 由移动应用程序使用的标识符。 |
密钥 | 否 | 通过集成门户提供的密钥。如果您只需要JWT令牌,则该字段为可选。 |
重定向方案 | 否 | 用于打开第三方应用的方案。(这要求第三方在Info.plist 文件中添加URL Types 方案。) |
Swift
let connect = Connect(applicationIdentifier: <INSERT APPLICATION IDENTIFIER HERE>,
mobileApplicationIdentifier: <INSERT MOBILE APPLICATION IDENTIFIER HERE>,
secret: <INSERT SECRET HERE>,
redirectScheme: <INSERT REDIRECT SCHEME HERE>)
Objective-C
CCConnect *connect = [[CCConnect alloc] initWithApplicationIdentifier:<INSERT APPLICATION IDENTIFIER HERE>
mobileApplicationIdentifier:<INSERT MOBILE APPLICATION IDENTIFIER HERE>
secret:<INSERT SECRET HERE>
redirectScheme:<INSERT REDIRECT SCHEME HERE>];
通过Info.plist
加载字段是一种初始化库的便捷方式。
Swift
let connect = try Connect.initialize(withBundle: Bundle.main, secret: <INSERT SECRET HERE>)
Objective-C
NSError *error;
NSBundle *bundle = [NSBundle mainBundle];
CCConnect *connect = [CCConnect initializeWithBundle:bundle secret:<INSERT SECRET HERE> error:&error];
库将通过Info.plist
遍历以下字段:
名称 | 类型 | 必需 |
---|---|---|
CFBundleIdentifier(包标识符 - 默认情况下应已存在) | 字符串 |
是 |
CivicApplicationIdentifier | 字符串 |
是 |
CivicSecret *已弃用 | 字符串 |
是 |
CivicRedirectScheme | 字符串 |
否 |
请注意:CivicRedirectScheme
要求您在Info.plist
中添加一个具有标识符至少一个方案的URL Type
。方案需要等于
CivicRedirectScheme
字段。
如果无法找到特定字段,则从Info.plist
加载字段可能会抛出以下错误:
错误 | 状态代码 | 消息 |
---|---|---|
cannotFindApplicationId | 901 | 找不到应用程序ID。请确保在您的Info.plist中存在'CivicApplicationIdentifier'。 |
cannotFindBundleId | 902 | 找不到包ID。请确保在您的Info.plist中存在'CFBundleIdentifier'。 |
cannotFindSecret | 903 | 找不到密钥。请确保在您的Info.plist中存在'CivicSecret'。 |
redirectSchemeMismatch | 904 | 找不到与'CivicRedirectScheme'匹配的URL方案。请确保'CivicRedirectScheme'与之一致'DFBundleURLTypes' CFBundleURLSchemes 。 |
连接
一旦创建了一个初始化的Connect
类实例,你就能开始应用程序与Civic之间的连接。为了发起一个流程,你可以使用Connect.connect(withType:delegate:)
方法
Swift
connect.connect(withType: .basic, delegate: self)
Objective-C
[connect connectWithType:CCScopeRequestTypeBasic delegate:self];
要确定使用哪种类型,你需要知道你需要哪些信息。以下表格显示了这些类型提供的信息
范围请求类型 | 描述 |
---|---|
HelloRequestType.basicSignup |
包括基本信息,如电子邮件 和电话号码 。 |
HelloRequestType.anonymousLogin |
仅包括用户ID。 |
HelloRequestType.proofOfResidence |
包括用户的基本信息,身份证明 和居留证明 。 |
HelloRequestType.proofOfIdentity |
包括基本信息,如电子邮件 和电话号码 以及有关身份证明 的信息。 |
HelloRequestType.proofOfAge |
包括用户的年龄。 |
代表者是库通过以下方法通过合作伙伴通讯的方式
方法 | 描述 |
---|---|
func connectDidFailWithError(_ error: ConnectError) |
当由于服务错误、会话错误等发生错误时,此方法被触发。 |
func connectDidFinishWithUserId(_ userId: String, andUserInfo userInfo: [UserInfo]) |
当ConnectSession 从服务器检索用户数据时,此方法被触发。 |
func connectDidChangeStatus(_ newStatus: ConnectStatus) |
当ConnectSession 的状态更改时,此方法被触发。它提供了一种简单的方式来了解后台发生了什么。 |
func connectShouldFetchUserData(withToken token: String) -> Bool |
当ConnectSession 收到来自服务器的JWT令牌时,此方法被触发。在这一点上,我们询问代表者是否应该继续使用JWT令牌检索用户数据。返回true将允许ConnectSession 检索用户数据,而返回false则结束会话。对于Swift,此方法默认实现并使用扩展返回true。 |
与Civic连接后,创建一个ConnectSession
来处理合作伙伴应用程序和Civic之间的连接。一旦创建了ConnectSession
,你就有了两种处理会话的方式。一种是通过Connect.handle(url:)
方法处理用于打开合作伙伴应用程序的URL
,另一种是调用Connect.startPollingForUserData()
方法。以下将描述这些方法。
URL
处理 处理一个 URL
将允许库确定公民应用程序是否打开了/重定向到合作伙伴应用程序,并开始检索用户数据。为了让此功能正常工作,必须在 Info.plist
中设置一个带有 URL 规约
的 URL 类型
。(请参见示例项目了解如何实现)
处理 URL
的一个方便位置是在 AppDelegate
中的 func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
方法如下
Swift
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return connect.handle(url: url)
}
Objective-C
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation {
return [connect handleUrl:url];
}
内部将检查该 URL
是否由公民应用程序启动。您可以通过 Connect.canHandle(url:)
手动检查 URL
。如果会话可以处理该 URL
,则它会内部调用 Connect.startPollingForUserData()
。
开始轮询用户数据
如果您不选择处理 URL
方法,或者您宁愿不使用重定向机制,您可以选择手动开始轮询用户数据。当调用此方法时,它将启动一个定时器,不断检查公民应用程序是否完成了流程。
Swift
connect.startPollingForUserData()
Objective-C
[connect startPollingForUserData];
停止轮询用户数据
在任何时候启动会话时,您可以通过调用Connect.stopPollingForUserData()
来使计时器失效。
Swift
connect.stopPollingForUserData()
Objective-C
[connect stopPollingForUserData];
重置
您可以通过调用Connect.reset()
函数来重置Connect
实例的状态。
Swift
connect.reset()
Objective-C
[connect reset];
连接按钮
如果您想要一个Civic风格的按钮,可以使用ConnectButton
类,它只是UIButton
的一个子类。为了创建一个,您需要提供一个Connect
实例、一个ConnectDelegate
,以及可选的ScopeRequestType
。
Swift
let connectButton = ConnectButton(<INSERT CONNECT HERE>,
type: <INSERT SCOPE REQUEST TYPE HERE (DEFAULTS TO .basic)>,
delegate: <INSERT CONNECT DELEGATE HERE>)
Objective-C
CCConnectButton *connectButton = [[CCConnectButton alloc] initWithConnect:<INSERT CONNECT HERE>
type:<INSERT SCOPE REQUEST TYPE HERE>
delegate:<INSERT CONNECT DELEGATE HERE>];
创建完毕后,您可以自定义按钮的标题和图片
Swift
connectButton.setConnectTitle(<INSERT TITLE HERE>, image: <INSERT IMAGE HERE>)
connectButton.setConnectTitle(<INSERT TITLE HERE>)
Objective-C
[connectButton setConnectTitle:<INSERT TITLE HERE> image:<INSERT IMAGE HERE>];
[connectButton setConnectTitle:<INSERT TITLE HERE>];
作用域请求类型也可以随时更改
Swift
connectButton.setType(<INSERT SCOPE REQUEST TYPE HERE>)
Objective-C
[connectButton setType:<INSERT SCOPE REQUEST TYPE HERE>];
任何时候轻触ConnectButton
按钮,它将开始连接到Civic应用程序,并在按钮上显示加载指示器。一旦会话接收到了错误或成功响应,加载指示器将消失。
错误
下表显示了通过库可能发生的潜在错误
错误 | 状态代码 | 消息 |
---|---|---|
cannotFindApplicationId | 901 | 找不到应用程序ID。请确保在您的Info.plist中存在'CivicApplicationIdentifier'。 |
cannotFindBundleId | 902 | 找不到包ID。请确保在您的Info.plist中存在'CFBundleIdentifier'。 |
cannotFindSecret | 903 | 找不到密钥。请确保在您的Info.plist中存在'CivicSecret'。 |
redirectSchemeMismatch | 904 | 找不到与'CivicRedirectScheme'匹配的URL方案。请确保'CivicRedirectScheme'与之一致'DFBundleURLTypes' CFBundleURLSchemes 。 |
cannotParseResponse | 911 | 无法解析来自服务器的响应。 |
cannotParseResponseData | 912 | 无法解析来自服务器的响应数据。 |
invalidUrl | 913 | 无效的URL。 |
invalidRequest | 914 | 无效请求。 |
invalidSession | 921 | 无效会话。 |
mobileUpgrade | 922 | 需要手机升级。 |
userCancelled | 923 | 用户取消了作用域请求。 |
verifyError | 924 | 验证过程中发生错误。 |
userDataNotAvailable | 202 | 用户数据仍然不可用。请稍后再尝试轮询。 |
scopeRequestTimeOut | 925 | 作用域请求超时。 |
verificationFailed | 931 | 验证响应失败。 |
decryptionFailed | 932 | 解密响应数据失败。 |
secretNotFound | 933 | 无法找到密钥。请确保您为库提供了有效的密钥。 |
decodingFailed | 997 | 解码JSON到对象失败。 |
authenticationUnknownError | 998 | 未知身份验证错误。 |
unknown | 999 | 未知错误。 |
下表显示了通过服务器API可能发生的潜在错误
错误 | 状态代码 | 消息 |
---|---|---|
badRequest | 400 | 检查响应的'message'字段以获取详细信息。 |
unauthorized | 401 | 身份验证失败。 |
methodNotAllowed | 405 | 您试图访问无效的方法。 |
insufficientFunds | 409 | 未经授权:余额不足。 |
tooManyRequests | 429 | 您的请求已被我们的网关限制。 |
internalServer | 500 | 我们服务器有问题。稍后重试。 |
timeOut | 504 | 端点请求超时异常。 |
常见问题解答(FAQ)
我们使用什么作为重定向方案?
您可以使用任何对您的应用有效的唯一方案。
UserInfo
中获取UIImage
?
我们如何从一些UserInfo
对象使用Base64编码存储值,例如,对于documents.genericId.image
的UserInfo
对象,我们可以使用以下代码片段进行解码,以将其解码为UIImage
:
func decodeBase64ToImage(_ userInfo: UserInfo) -> UIImage? {
guard let data = Data(base64Encoded: userInfo.value, options: .ignoreUnknownCharacters) else {
return nil
}
return UIImage(data: data)
}
Unauthorized: no platforms found for provided app_id
时,意味着什么?
当我收到这意味着你提供的应用标识符不正确。请确保你在配置的应用下从集成门户中获得了正确的App ID。
Unauthorized: mobileId not found in partner platform list
时,意味着什么?
当我收到这表示你没有提供正确的Bundle ID,或者你没有在集成门户上配置你的移动应用程序。
我该如何仅检索JWT令牌以便在我的端处理用户数据?
为了仅检索JWT令牌,在你的ConnectDelegate
实现中,实现func connectShouldFetchUserData(withToken token: String) -> Bool
函数并返回false。该函数中提供的token
是JWT令牌,可以通过所需的方式进行处理。
作者
请参阅参与此项目的贡献者列表。
贡献
在CONTRIBUTING文件中查找贡献指南。
许可证
Civic App Connect 在MIT许可证下可用。有关更多信息,请参阅LICENSE文件。