1Password是啥我在这里不再赘述,不了解的话可以去官网了解一下~
1Password可以方便的存储我们的账号密码,而且生成的账号密码非常复杂,安全性非常高。如果我们的app也支持1Password,那无疑会方便用户,而且提高我们app的“bigger”
1Password开发网站在GitHub上,里面介绍比较详细,我也是刚刚看完它的readme,然后过来卖弄。
1. 集成1Password需要三个文件
图片集、头文件、实现文件
2.编辑URLScheme
因为需要跳转,在iOS9系统里,需要配置URLScheme,
在工程的plist文件中,添加LSApplicationQueriesSchemes数组,并且在数组内添加一个名为org-appextension-feature-password-management的成员就可以了
3.增加1Password按键
在xib中增加一个按键,图标在1Password.xcassets上有
这个按键在有1Password服务的时候显示,否则不显示
self.onePassBtn.hidden = ![[OnePasswordExtension sharedExtension] isAppExtensionAvailable];
4. 集成1Password需要实现三种功能
下面我们就可以集成1Password了,需要集成的地方有三个:注册账号时,登陆时,修改密码时
注册账号:(保存账号密码)
- (IBAction)saveLoginTo1Password:(id)sender {
NSDictionary *newLoginDetails = @{
AppExtensionTitleKey: @"XX客户端账号",
AppExtensionUsernameKey: self.nameLabel.text ? : @"",
AppExtensionPasswordKey: self.passLabel.text ? : @"",
AppExtensionNotesKey: @"在XX客户端中保存",
};
// The password generation options are optional, but are very handy in case you have strict rules about password lengths, symbols and digits.
NSDictionary *passwordGenerationOptions = @{
// The minimum password length can be 4 or more.
AppExtensionGeneratedPasswordMinLengthKey: @(6),
// The maximum password length can be 50 or less.
AppExtensionGeneratedPasswordMaxLengthKey: @(20),
// If YES, the 1Password will guarantee that the generated password will contain at least one digit (number between 0 and 9). Passing NO will not exclude digits from the generated password.
AppExtensionGeneratedPasswordRequireDigitsKey: @(YES),
// If YES, the 1Password will guarantee that the generated password will contain at least one symbol (See the list bellow). Passing NO with will exclude symbols from the generated password.
AppExtensionGeneratedPasswordRequireSymbolsKey: @(NO),
// Here are all the symbols available in the the 1Password Password Generator:
// !@#$%^&*()_-+=|[]{}'\\";.,>?/~`
// The string for AppExtensionGeneratedPasswordForbiddenCharactersKey should contain the symbols and characters that you wish 1Password to exclude from the generated password.
AppExtensionGeneratedPasswordForbiddenCharactersKey: @"!@#$%/lIO"
};
[[OnePasswordExtension sharedExtension] storeLoginForURLString:@"XX客户端" loginDetails:newLoginDetails passwordGenerationOptions:passwordGenerationOptions forViewController:self sender:sender completion:^(NSDictionary *loginDictionary, NSError *error) {
if (loginDictionary.count == 0) {
if (error.code != AppExtensionErrorCodeCancelledByUser) {
NSLog(@"Failed to use 1Password App Extension to save a new Login: %@", error);
}
return;
}
self.nameLabel.text = loginDictionary[AppExtensionUsernameKey] ? : @"";
self.passLabel.text = loginDictionary[AppExtensionPasswordKey] ? : @"";
// retrieve any additional fields that were passed in newLoginDetails dictionary
}];
}
原理很简单,首先传入用户名和密码,如果用户在使用1Password保存账号密码之前,已经输入好了账号密码,那么就会直接带进1Password中,如果没有输入则传入为空,无论是否为空,都可以在1Password内继续修改账号密码
之后是声明对密码的限制,比如最大最小长度,是否允许特殊字符,规避的字符等
执行下面这个方法以后,会调用block内容
- (void)storeLoginForURLString:(nonnull NSString *)URLString loginDetails:(nullable NSDictionary *)loginDetailsDictionary passwordGenerationOptions:(nullable NSDictionary *)passwordGenerationOptions forViewController:(nonnull UIViewController *)viewController sender:(nullable id)sender completion:(nullable void (^)(NSDictionary * __nullable loginDictionary, NSError * __nullable error))completion ;
第一个参数URLString是我们这个应用的标志符,一般是一个网址,但是我发现用随便一个字符串也可以。
调用完成以后,会弹到1Password
用户编辑完账号密码,点击完成以后,block内会对账号密码的输入框重新赋值
登陆:(获取账号密码)
- (IBAction)findLoginFrom1Password:(id)sender {
[[OnePasswordExtension sharedExtension] findLoginForURLString:@"XX客户端" forViewController:self sender:sender completion:^(NSDictionary *loginDictionary, NSError *error) {
if (loginDictionary.count == 0) {
if (error.code != AppExtensionErrorCodeCancelledByUser) {
NSLog(@"Error invoking 1Password App Extension for find login: %@", error);
}
return;
}
self.nameLabel.text = loginDictionary[AppExtensionUsernameKey];
self.passLabel.text = loginDictionary[AppExtensionPasswordKey];
}];
}
读取是最简单的,只需要带入我们的URLString就可以了
修改密码:
- (IBAction)changePasswordIn1Password:(id)sender {
NSString *changedPassword = self.anewPassLabel.text ? : @"";
NSString *oldPassword = self.passLabel.text ? : @"";
NSDictionary *loginDetails = @{
AppExtensionTitleKey: @"XX客户端账号", // Optional, used for the third schenario only
AppExtensionPasswordKey: changedPassword,
AppExtensionOldPasswordKey: oldPassword,
AppExtensionNotesKey: @"在XX客户端中保存", // Optional, used for the third schenario only
};
// The password generation options are optional, but are very handy in case you have strict rules about password lengths, symbols and digits.
NSDictionary *passwordGenerationOptions = @{
// The minimum password length can be 4 or more.
AppExtensionGeneratedPasswordMinLengthKey: @(6),
// The maximum password length can be 50 or less.
AppExtensionGeneratedPasswordMaxLengthKey: @(20),
// If YES, the 1Password will guarantee that the generated password will contain at least one digit (number between 0 and 9). Passing NO will not exclude digits from the generated password.
AppExtensionGeneratedPasswordRequireDigitsKey: @(YES),
// If YES, the 1Password will guarantee that the generated password will contain at least one symbol (See the list bellow). Passing NO with will exclude symbols from the generated password.
AppExtensionGeneratedPasswordRequireSymbolsKey: @(NO),
// Here are all the symbols available in the the 1Password Password Generator:
// !@#$%^&*()_-+=|[]{}'\\";.,>?/~`
// The string for AppExtensionGeneratedPasswordForbiddenCharactersKey should contain the symbols and characters that you wish 1Password to exclude from the generated password.
AppExtensionGeneratedPasswordForbiddenCharactersKey: @"!@#$%/lIO"
};
[[OnePasswordExtension sharedExtension] changePasswordForLoginForURLString:@"XX客户端" loginDetails:loginDetails passwordGenerationOptions:passwordGenerationOptions forViewController:self sender:sender completion:^(NSDictionary *loginDictionary, NSError *error) {
if (loginDictionary.count == 0) {
if (error.code != AppExtensionErrorCodeCancelledByUser) {
NSLog(@"Error invoking 1Password App Extension for find login: %@", error);
}
return;
}
self.passLabel.text = loginDictionary[AppExtensionOldPasswordKey];
self.anewPassLabel.text = loginDictionary[AppExtensionPasswordKey];
}];
}
跟保存类似,首先传入老、新密码(但是貌似传老密码没什么卵用,老密码采使用的是进入1Password以后,选择的账号的密码)。
然后配置密码的限制,进入1Password,设置好了以后,在完成的block中修改老、新密码的内容,老的填上次存储的,新的填刚改的
至此,1Password就集成完了。
你可以在官方GitHub上运行Demo代码看看效果。
PS:
我之前没用过1Password,但是我发现了一个不太好的地方,注册的时候,如果已经有一个叫xiaoming的账号,密码是123456,我再注册一个xiaoming,密码是qwerty,保存以后,1Password里会有两个xiaoming账号,而且密码都变成了qwerty,不知道是不是Demo代码有问题。总之官方的Demo也是这样,一直没找到原因,求指导