概述
一、前言
Valet 可以帮助你实现将数据安全地存储在 iOS 或 OS X Keychain 中,而无需了解任何 Keychain 相关的工作原理。它支持在单个设备上的多个应用程序(同一开发者)之间共享数据,并在具有 iCloud 的设备上的实现跨设备的数据共享。它还支持 Touch ID 。
二、实现数据共享
本文通过ValetDemo改变BundleID,使用同一证书打出两个APP以及修改相关的设置,实现同一开发者下的这两个APP间的文字图像数据共享。
步骤如下:
1、 首先通过pod 'Valet'
安装Valet
2、 初始化Valet。为了查看效果需要两个APP向valet储存不同值,点击saveButton根据不同的BundleID向valet储存不同值,点击getButton获取valet中的文字及图像,点击removeButton清空valet中的数据。
ValetDemo结构如下:
ValetViewController的代码如下:
ValetViewController.h
#import <UIKit/UIKit.h>
@interface ValetViewController : UIViewController
@end
ValetViewController.m
#import "ValetViewController.h"
#import <Valet.h>
@interface ValetViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *contentImageView;
@property (weak, nonatomic) IBOutlet UILabel *contentLabel;
@property (strong, nonatomic) VALValet *myValet;
@end
@implementation ValetViewController
#pragma mark - Life Cycle
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.myValet = [[VALValet alloc] initWithSharedAccessGroupIdentifier:@"com.pingan.csp.common" accessibility:VALAccessibilityWhenPasscodeSetThisDeviceOnly];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - IBAction
- (IBAction)clickSaveButton:(id)sender {
BOOL isFisrtApp = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"] isEqualToString:BundleID];
if (isFisrtApp) {
UIImage *image = [UIImage imageNamed:@"headIcon"];
[self.myValet setObject:UIImageJPEGRepresentation(image, 1.0) forKey:@"myHeadIcon"];
[self.myValet setString:@"Doge" forKey:@"myName"];
}else{
UIImage *image = [UIImage imageNamed:@"headIcon2"];
[self.myValet setObject:UIImageJPEGRepresentation(image, 1.0) forKey:@"myHeadIcon"];
[self.myValet setString:@"Cat" forKey:@"myName"];
}
}
- (IBAction)clickGetButton:(id)sender {
NSData *imageData = [self.myValet objectForKey:@"myHeadIcon"];
self.contentImageView.image = [UIImage imageWithData:imageData];
self.contentLabel.text = [self.myValet stringForKey:@"myName"];
}
- (IBAction)clickDeleteButton:(id)sender {
[self.myValet removeAllObjects];
}
@end
ValetDemo.storyboard
3、 工程配置(关键)
因为当初查看GitHub上文档说明太简单,没有说明如何配置工程,也没有keyChain的相关知识。所以在这里走了很多弯路。工程配置如下:
打开Keychain Sharing,然后在里面配置一个common公共的keychainGroup,另一个是自用的keychainGroup。PS:不一定要用BundleID作为标记。配置完,你会发现工程多了一个.entitlements文件,里面会有对应的keychainGroup。
demo1配置如下:
demo2配置如下:
Demo通过entitlement中的keychainGroup进行授权访问,这里Demo1和Demo2都可以通过访问$(AppIdentifierPrefix)com.pingan.csp.common来share数据。$(AppIdentifierPrefix)指的是seedID,seedID是开发者账号对应的一个ID如下图红色圈所示:
因此$(AppIdentifierPrefix)com.pingan.csp.common等于seedID.com.pingan.csp.common,两个Demo的访问keychain的权限如下:
我们通过- (nullable instancetype)initWithSharedAccessGroupIdentifier:(nonnull NSString *)sharedAccessGroupIdentifier accessibility:(VALAccessibility)accessibility这个方法以seedID.com.pingan.csp.common为identifier来初始化valet,这样我们就可以通过entitlement来访问keychain。
self.myValet = [[VALValet alloc] initWithSharedAccessGroupIdentifier:@"com.pingan.csp.common" accessibility:VALAccessibilityWhenPasscodeSetThisDeviceOnly];
PS:valet的方法已经在里面封装拼接SeedID,所以我们使用的时候只需要把com.pingan.csp.common传入即可。这个是后来我打断点才发现的,之前一直把seedID也传进来导致与entitlements的keychainGroup不匹配在另一个demo取不到值。另外valet的方法也没有对这一点进行说明。
4、 方法、参数的解释及应用场景
(1) 方法
1) 适用于应用间不共享的
VALValet *myValet = [[VALValet alloc] initWithIdentifier:@"Druidia" accessibility:VALAccessibilityWhenUnlocked];
2) 适用于应用间分享
VALValet *mySharedValet = [[VALValet alloc] initWithSharedAccessGroupIdentifier:@"Druidia" accessibility:VALAccessibilityWhenUnlocked];
PS:即使identifer相同,也不能与上一个方法取到相同valet和值,所以储存值的时候要注意方法。
3) 适用于TouchID
VALSecureEnclaveValet *mySecureEnclaveValet = [[VALSecureEnclaveValet alloc] initWithIdentifier:@"Druidia" accessControl:VALAccessControlUserPresence];
PS:需要iOS8.0以上及5s(含5s)以后的设备支持TouchID
(2) VALAccessibility参数
VALAccessibilityWhenUnlocked = 1,
VALAccessibilityAfterFirstUnlock,
VALAccessibilityAlways,
VALAccessibilityWhenPasscodeSetThisDeviceOnly NS_ENUM_AVAILABLE(10_10, 8_0),
VALAccessibilityWhenUnlockedThisDeviceOnly,
VALAccessibilityAfterFirstUnlockThisDeviceOnly,
VALAccessibilityAlwaysThisDeviceOnly,
参数总体分成两类,有后缀DeviceOnly说明只有本设备,没有则表示可以跨设备
VALAccessibilityWhenUnlocked没有锁屏,VALAccessibilityAfterFirstUnlock第一次解锁屏幕,VALAccessibilityAlways总是可以。
(3) 应用场景
valet本质是对keychain的封装,其实就是keychian的应用场景。
场景一是进行跨设备or跨应用的数据共享;另一个场景是单个app删除后,重新安装app可以马上读取keychain的内容,这样保存了用户之前的设置。另一方面keychain可能存在安全方面的问题,尽量不要明文储存敏感信息。
如果大家有关于数据共享更好的想法,欢迎大家一起讨论,谢谢。
最后
以上就是发嗲煎蛋为你收集整理的 Valet实现应用间数据共享的全部内容,希望文章能够帮你解决 Valet实现应用间数据共享所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复