iOS - 第三下输入法App原理调研、App Group数据共享(下)

简介: 本文Demo同步Github

2.3 键盘UI布局


我把源码上传到了Github


CCInput


键盘的UI布局我以简单以搜狗输入法的数字键盘为例,这里附上代码说明,具体请查看Demo代码


KeyboardViewController 创建keyboard extension时,系统自动创建的vc,继承自UIInputViewController,键盘的布局、逻辑处理都在此类中


CCLeftTableView 左侧符号输入,是一个TabView,,支持增加符号数据源

CCCenterView 中间数字键盘及底部切换、数字0、空格功能


CCRightView 右侧删除、句号、@符号、换行功能


CCKeyboardModel 键盘数据源Model,Model有两个属性,分别是

NSString *string 用于键盘按钮文本的展示


CCKeyboardAction keyboardAction 是点击事件的枚举类型,点击键盘的时候通过此属性统一处理


简单的写了个通过runtime自动获取属性解析json为model的方法


主要是UI和数据结构,此处不深入探究,感兴趣请看demo,此处有个自定义键盘高度的坑注意下:


  1. 通过简单的setframe无法更改键盘默认高度


  1. 需要通过设置NSLayoutConstraint的方式,切在viewDidLoad方法中设置无效


  1. 需在viewDidAppear之前设置键盘高度


这个问题的解决方案因为国内做键盘的公司比较少,百度搜索不到相关资料,附上stackoverflow链接


stackoverflow: iOS 8 Custom Keyboard: Changing the Height


Demo效果:


image.png

https://upload-images.jianshu.io/upload_images/1903571-a3874c99894ea210.image?imageMogr2/auto-orient/strip|imageView2/2/w/421/format/webp

Demo效果.gif


同时附上Demo中代码

static CGFloat KEYBOARDHEIGHT = 256;
@interface KeyboardViewController ()
<CCTopBarDelegate,
CCLeftViewDelegate,
CCCenterViewDelegate,
CCRightViewDelegate>
/// 用于设置键盘自定义高度
@property (nonatomic, assign) NSLayoutConstraint *heightConstraint;
@end
@implementation KeyboardViewController
- (void)prepareHeightConstraint {
    if (self.heightConstraint == nil) {
        UILabel *dummyView = [[UILabel alloc] initWithFrame:CGRectZero];
        dummyView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.view addSubview:dummyView];
        self.heightConstraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:KEYBOARDHEIGHT];
        self.heightConstraint.priority = 750;
        [self.view addConstraint:self.heightConstraint];
    } else {
        self.heightConstraint.constant = KEYBOARDHEIGHT;
    }
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self prepareHeightConstraint];
}
/// 重写的父类方法,苹果建议在此处updateViewConstraints
- (void)updateViewConstraints {
    [super updateViewConstraints];
    if (self.view.frame.size.width == 0 && self.view.frame.size.height == 0) {
        return;
    }
    [self prepareHeightConstraint];
}


UIInputViewController 涉及到的方法说明:


  • advanceToNextInputMode 切换到下一个输入法


  • dismissKeyboard 退出键盘(相当于resignFirstResponder


  • insertText 插入文本(尾部)


  • deleteBackward 删除输入框内上一个文本


3. 输入法类App原理


3.1 主程序与键盘拓展的关系


image.png


图源自网络


第三方输入法,分为主程序(containing App)、键盘(extension), 分别对应Demo中的InputAppCustomKeyboard, 主程序在桌面可见,Host App则是使用输入法的其它App,


  • 主程序和键盘Extension正常情况是无法共享数据的(沙箱隔离)
  • 在开启完全访问时,主程序和键盘Extension可以共享数据(通过app groups)
  • 主程序和Host App无法共享数据(沙箱隔离)
  • 键盘Extension和Host App只能共享文本数据(通过系统UITextDocumentProxy)


3.2 完全访问


在设置-通用-键盘中,苹果有对完全访问做说明,摘录如下


第三方键盘提供了另一种途径来键入键盘数据。这些键盘可以访问您键入的所有数据,包括银行账户、信用卡号码、街道地址及其他个人信息与敏感信息。这些键盘还可能访问相邻文本及数据,这些信息对改进自动更正功能卓有帮助。


如果您启用“完全访问”,开发者即获得许可访问、收集与传输您键入的数据。此外,如果附带键盘的第三方应用程序获得您的许可访问地理位置信息、照片、或其他个人数据,那么此键盘也可收集并将该信息传输至键盘开发者的服务器上。如果您停用某第三方键盘的“完全访问”,之后再重新启用,那么键盘开发者则可能能够访问、收集并传输网络访问禁用期间所键入的信息。


如果您不启用“完全访问”,那么开发者则不可收集与传输您键入的数据。未经您许可,任何未授权的数据收集或传输行为均违反其开发者协议。此外,技术限制同样在防止未经许可的访问方面起作用。任何试图破坏此类限制的尝试同样违反开发者协议。


你任何时候均可选择停用第三方键盘。打开“设置”,轻点“键盘”,将该键盘从键盘列表中移除即可。


如果您使用第三方键盘,即需遵守键盘开发者的条款、隐私政策及做法。使用此类键盘App与服务之前,您应仔细阅读其条款、隐私政策和做法,以了解他们如何使用您的数据及其他信息。


总结就是,只有开启了完全访问,输入法App才能:


  • 访问、收集、传输输入的数据
  • 访问并上传位置、照片、个人数据(通讯录之类权限隐私数据)
  • 如果开启之后又关闭,那么开发者还是能够传输禁用期间的数据
  • 如果不开启,那么因为苹果的技术限制(沙箱),开发者并不能上传键盘Extension获取到的数据


3.3 App Groups数据共享


官方文档:Sharing Data with Your Containing App


image.png

app_extensions_container_restrictions_2x.png


简单来说,开启了app groups,相当于生成一个中间数据共享区(shared container)来将App's containerExtension's container的数据关联并共享


通过以下方式就可以共享数据

// Create and share access to an NSUserDefaults object
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"com.example.domain.MyShareExtension"];
// Use the shared user defaults object to update the user's account
[mySharedDefaults setObject:theAccountName forKey:@"lastAccountName"];


4 输入法App和逆向(个人瞎猜,可能鲁迅人本身根本没这么想)


通过上文3.13.23.3我们知道, 主App和Extension之间要想共享数据,必须开启完全访问通过App Groups的方式共享数据,对于一款键盘类App,他肯定是希望App和Extension能实现数据共享,以达到以下需求:


  • 实时更新网络高频热词,用于联想输入
  • 共享键盘皮肤
  • 存储用户高频输入的词汇、通讯录等数据,上传服务端,当用户换设备时,能同步并共享给新设备的Extension


但是由于沙箱的限制,如果用户没有开启完全访问,以上三点需求就达不成了。事实上以上三点需求对我这样的用户来说非常重要,无缝衔接切换设备的快感是无法形容的,比如当我在iPhone上输入ma后,我选择了联想词汇表中的码代码的小马,然后当我在mac上使用搜狗输入法同样输入ma,mac也联想到了码代码的小马,这样会将我的输入效率提高很多


此时就用到了逆向技术


苹果有沙箱隔离,逆向里有沙箱逃脱(沙箱逃脱详细解释请参考我之前文章沙箱逃脱)

沙箱逃脱简单来说就是跨进程访问数据共享数据,放在这里就是,即使用户不开启完全访问,主App也能访问Extension的数据,以实现如上三点需求。


只是目前沙箱逃脱技术只能在越狱设备实现,也许未来某一天某个大牛实现了在未越狱设备的沙箱逃脱,那对于逆向开发者来说,简直是这盛世如你所愿,大好河山任你看...


相关文章
|
13天前
|
API 数据安全/隐私保护 iOS开发
利用uni-app 开发的iOS app 发布到App Store全流程
利用uni-app 开发的iOS app 发布到App Store全流程
116 3
|
13天前
|
存储 运维 安全
iOS加固原理与常见措施:保护移动应用程序安全的利器
iOS加固原理与常见措施:保护移动应用程序安全的利器
37 0
|
12天前
|
Android开发 移动开发 小程序
binder机制原理面试,安卓app开发教程
binder机制原理面试,安卓app开发教程
binder机制原理面试,安卓app开发教程
|
13天前
|
Android开发 iOS开发 开发者
App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法
App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法
171 0
|
4天前
如何解决iOS16系统app首次启动总是弹出允许粘贴提示框问题
如何解决iOS16系统app首次启动总是弹出允许粘贴提示框问题
8 0
如何解决iOS16系统app首次启动总是弹出允许粘贴提示框问题
|
5天前
|
移动开发 网络协议 Linux
We discovered one or more bugs in your app when reviewed on iPhone and iPad running iOS 14.1
We discovered one or more bugs in your app when reviewed on iPhone and iPad running iOS 14.1
10 0
|
7天前
|
定位技术 开发工具 iOS开发
ios9定位服务的app进入后台三分钟收不到经纬度,应用被挂起问题及解决方案
ios9定位服务的app进入后台三分钟收不到经纬度,应用被挂起问题及解决方案
10 0
|
7天前
|
大数据 测试技术 数据库
ios app性能分析
ios app性能分析
14 2
|
7天前
|
iOS开发 网络架构 UED
ios app的分类与本质,感想
ios app的分类与本质,感想
11 0
|
13天前
|
开发者 iOS开发
iOS App上架新规解析:如何进行App备案
iOS App上架新规解析:如何进行App备案
336 0