Valet实现应用间数据共享

一、前言

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结构如下:

结构1

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

结构2

3、 工程配置(关键)

因为当初查看GitHub上文档说明太简单,没有说明如何配置工程,也没有keyChain的相关知识。所以在这里走了很多弯路。工程配置如下:

1

打开Keychain Sharing,然后在里面配置一个common公共的keychainGroup,另一个是自用的keychainGroup。PS:不一定要用BundleID作为标记。配置完,你会发现工程多了一个.entitlements文件,里面会有对应的keychainGroup。

6

demo1配置如下:

2

3

demo2配置如下:

4

5

Demo通过entitlement中的keychainGroup进行授权访问,这里Demo1和Demo2都可以通过访问$(AppIdentifierPrefix)com.pingan.csp.common来share数据。$(AppIdentifierPrefix)指的是seedID,seedID是开发者账号对应的一个ID如下图红色圈所示:

7

因此$(AppIdentifierPrefix)com.pingan.csp.common等于seedID.com.pingan.csp.common,两个Demo的访问keychain的权限如下:

8

我们通过- (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的方法也没有对这一点进行说明。

9

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可能存在安全方面的问题,尽量不要明文储存敏感信息。

如果大家有关于数据共享更好的想法,欢迎大家一起讨论,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值