本篇简单介绍下,使用的三方授权以及简单维护的几个flutter原生插件
三方登录
苹果登录
三方库: sign_in_with_apple | Flutter Package (pub.dev)
- Xcode内配置需要的权限
- dart端代码实现
final credential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
);
final id = credential.userIdentifier;
final idToken = credential.identityToken;
facebook登录(需翻墙)
三方库: flutter_login_facebook | Flutter Package (pub.dev)
- Xcode内配置需要的权限
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb[APP_ID]</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>[APP_ID]</string>
<key>FacebookClientToken</key>
<string>[CLIENT_TOKEN]</string>
<key>FacebookDisplayName</key>
<string>[APP_NAME]</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
</array>
配置完成后生成urltype
- dart端代码实现,注意facebook登录需要翻墙
// 创建实例
static final FacebookLogin facebookSignIn = FacebookLogin();
// 授权
static Future<ThirdAuth> signInFacebook() async {
final res = await facebookSignIn.logIn(
permissions: [
FacebookPermission.publicProfile,
FacebookPermission.email,
],
);
// Check result status
switch (res.status) {
case FacebookLoginStatus.success:
// Send access token to server for validation and auth
final FacebookAccessToken? accessToken = res.accessToken;
final userId = accessToken?.userId;
final token = accessToken?.token;
if (accessToken == null || userId == null || token == null) {
throw Exception('cancel'.tr);
} else {
debugPrint('user Id: $userId \n Access token: $token');
return ThirdAuth(userId, token);
}
case FacebookLoginStatus.cancel:
throw BaseException(0, 'cancel'.tr);
case FacebookLoginStatus.error:
debugPrint('Error while log in: ${res.error}');
throw BaseException(0, 'error'.tr);
}
}
google登录(需翻墙)
google_sign_in | Flutter Package (pub.dev)
- Xcode内配置需要的权限 这一步按照该三方库介绍一步一步按照顺序来
注意点:
GoogleService-Info.plist是控制台配置完成后下载下来的,拖到xcode里面,server_client_id可以在dart端配置,就是初始化googlesignin实例的clientid实例,在iOS原生端使用的时候,原来的clientid格式是com.googleusercontent.apps.*******,但是在dart端,你需要写成********.apps.googleusercontent.com,这一点很容易忽略,而且很容易出错
// 创建实例
static final GoogleSignIn _googleSignIn = GoogleSignIn(
clientId: Platform.isIOS
? '****你的授权id******'
: '****你的授权id******',
scopes: <String>[
'email',
],
);
// 授权
static Future<ThirdAuth> signInWithGoogle() async {
try {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth =
await googleUser!.authentication;
final idToken = googleAuth.idToken;
final id = googleUser.id;
if (idToken == null) {
throw BaseException(0, 'error'.tr);
}
return ThirdAuth(id, idToken);
} catch (e) {
throw BaseException(0, 'error'.tr);
}
}
文件上传
从这里开始,后面的都是一些自己维护的插件,flutter插件写起来还是比较容易的,iOS这边比较重要的是要会写podspec,这个还是需要认真学一下podspec的规则写法.
aws3
pub.dev中的aws3库的都不太好用,所以这里是我和安卓童鞋一起维护的plugin
这里我就只简单贴一下iOS这边的原生实现,其实也是很简单,原生的代码拖过来稍微改一下即可(原生是别人写的,我只是简单增加了个rx的拓展),设计隐私文件夹,bucket什么的就不展示了
/// 初始化配置
/// - Parameters:
/// - key:
/// - secret:
/// - region:
static func config(accessKey: String, secretKey: String, bucketRegion: String, bucketName: String) {
let provider = AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
guard _transferUtility == nil else {
return
}
guard let configuration = AWSServiceConfiguration(
region: getAwsRegion(keyStr: bucketRegion),
credentialsProvider: provider
) else {
return
}
rootBucketName = bucketName
let transferConfig = AWSS3TransferUtilityConfiguration()
transferConfig.retryLimit = 3
transferConfig.multiPartConcurrencyLimit = 10
transferConfig.timeoutIntervalForResource = 30
AWSS3TransferUtility.register(
with: configuration,
transferUtilityConfiguration: transferConfig,
forKey: "transfer-utility-with-advanced-options"
)
_transferUtility = AWSS3TransferUtility.s3TransferUtility(forKey: "transfer-utility-with-advanced-options")
}
static func upload(
filePath: String,
name: String,
bucket: String,
contentType: String,
progressBlock: ((Progress) -> ())?,
success: @escaping (String) -> (),
failure: @escaping (Error) -> ()
) {
guard let transferUtility = _transferUtility else {
failure(NSError(domain: "初始化未完成", code: -1))
return
}
guard let fileURL = URL(string: filePath) else {
failure(NSError(domain: "文件不存在", code: -1))
return
}
let progressHandler = AWSS3TransferUtilityUploadExpression()
progressHandler.progressBlock = { (task, progress) in
progressBlock?(progress)
}
let key = bucket + "/" + name
transferUtility.uploadFile(
fileURL,
bucket: rootBucketName ?? "",
key: key,
contentType: contentType,
expression: progressHandler,
completionHandler: { task, error in
DispatchQueue.main.async {
if let error = task.error{
failure(error)
} else {
//AWSS3TransferUtilityUploadTask *uploadTask = task.result; Do something with uploadTask.
debugPrint("upl ???")
success(task.key)
}
}
}
)
.continueWith { task in
DispatchQueue.main.async {
if let error = task.error{
failure(error)
}
}
return nil
}
}
// 增加rx的拓展
static func upload(filePath: String,
name: String,
bucket: String,
contentType: String,
needHUD: Bool = true
) -> Single<String> {
return Single<Void>
.just(())
.delay(.milliseconds(300), scheduler: MainScheduler.asyncInstance)
.flatMap ({ _ in
Single<String>.create { signle in
FileUploader.upload(
filePath: filePath,
name: name,
bucket: bucket,
contentType: contentType,
progressBlock: { progress in
let percentage = Int(progress.fractionCompleted * 100)
debugPrint(percentage)
}, success: { path in
signle(.success(path))
}, failure: { error in
signle(.failure(error))
})
return Disposables.create()
}
})
.subscribe(on: MainScheduler.asyncInstance)
}
google人机安全校验(需翻墙)
这个没有android有sdk可以直接调用,iOS没有sdk,需要自己创建plugin分别维护 谷歌人机安全校验,,使用的是网上的方案,一个静态网页加载,注意一段js,这里就不贴了
IM
smartfox
IM消息通信是项目的核心,dart这边使用的是原生迁移过来的功能,然后做一层plugin抹平平台差异,这个东西用的人很少,就不细讲了,需要做的也挺多的,主要是做插件的通信,算是项目的重点,这里就不贴了,这个功能开发需要很久.
tracker
埋点也是原生维护,做迁移.