shaggon

杜晔的博客


  • 首页

  • 归档

  • 标签

Universal Link的优先权

发表于 2018-03-16
  • It is usual to use one universal link in one app.
  • It is also usual to use one universal link in one app for different scheme witch is using different bundle Id.
  • But it is unusual for mutable apps installed in the same device which are using mutable universal link in different priority.

For QA Testing, we’re setting someDebug,InHouse,Release-Candidate into apple-app-site-association.There’s no problems happened befor, because users can’t install a Debug version, and also the test device did not have to install a life version.

What is universal link

If you already know what isuniversal linkyou can skip this part
If you don’t know what isuniversal linkyou should read this apple’s doc first =>
clickMe
And this is a simple description↓

universal linkis a technique that can make your apps wake up and deep linking to a target page while user click some normal url like https://shaggon.com/man/322113 in safari,mail,message or social media apps.

  • There’re only two steps to implementationuniversal link

    1. Add the domain(for example: applinks:shaggon.com) in Capabilities => Associated Domains
    2. Add a file namedapple-app-site-association at the root of the server, make sureshaggon.com/apple-app-site-associationis visible. content is like below↓
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    {
    "applinks": {
    "apps": [],
    "details": [
    {
    "appID": "9JA89QQLNQ.com.apple.wwdc",
    "paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
    },
    {
    "appID": "ABCD1234.com.apple.wwdc",
    "paths": [ "*" ]
    }
    ]
    }
    }

The priority

Let’s back to the question

mutable apps installed in the same device which are using mutable universal link in different priority

We can find this in apple’s Doc:

The value of the details key is an array of dictionaries, one dictionary per app that your website supports. The order of the dictionaries in the array determines the order the system follows when looking for a match, so you can specify an app to handle a particular part of your website.

It looks like we can adjust the priorities of the dictionary inside the array of details to make that work.
Let’s try it!

  • PREPARE
    • https://shaggon.com/apple-app-site-association <– A First
    • https://www.doruby.com/apple-app-site-association <– B First
    • A clean Simulator iPhone 7
    • Installed app A
    • Installed app B
  • TEST


















Device installed A&B Device installed A Only Device installed B Only
A First A Opened A Opened B Opened
B First B Opened A Opened B Opened

CONCLUSION

Just like apple’s doc said,universal linkdose have the priority for different apps, what you need to do is to change the order of the different apps inside the array of detail.


  • 一个app使用一个universal link很普遍
  • 一个app的多个使用不同bundle Id的scheme共用一个universal link也很常见
  • 多个app使用多个universal link且在同时安装多个app的设备上需要保证不一样的link实现不一样的跳转优先级这个就不常见了。

我们天生的会把Debug,InHouse,Release-Candidate等的记录填写在apple-app-site-association中,以供QA在测试机上使用。我们没有发生过任何问题,因为正式用户不可能安装任何非life版本,而测试机也不怎么安装life版本。

什么是universal link

如果你已经知道universal link是什么的话可以先略过这一部分
如果你不明白什么是universal link你可以先阅读这份苹果的文档 =>
点我
然后下面是一份简单浅显的说明↓

universal link是一种可以让iOS用户通过在浏览器、邮件、短信、或社交软件中点击一个普通的url例如https://shaggon.com/man/322113而直接唤醒app并深度链接到指定页面的技术。

  • 实现universal link只需要做两步

    1. 在工程的Capabilities => Associated Domains中加入domain名字,例如applinks:shaggon.com
    2. 在domain所对应的网站根目录下添加如下的一个名叫apple-app-site-association的文件,使得shaggon.com/apple-app-site-association可供访问。内容如下↓需要关注和修改的点在details下面的一个包含着多个字典的数组中,它用来描述这个universal link的哪些path被哪个team的哪个bundleID的app所支持。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    {
    "applinks": {
    "apps": [],
    "details": [
    {
    "appID": "9JA89QQLNQ.com.apple.wwdc",
    "paths": [ "/wwdc/news/", "/videos/wwdc/2015/*"]
    },
    {
    "appID": "ABCD1234.com.apple.wwdc",
    "paths": [ "*" ]
    }
    ]
    }
    }

优先级问题

让我们再次回到问题

多个app使用多个universal link且在同时安装多个app的设备上需要保证不一样的link实现不一样的跳转优先级

在苹果的文档中我们可以发现这样一句话:

The value of the details key is an array of dictionaries, one dictionary per app that your website supports. The order of the dictionaries in the array determines the order the system follows when looking for a match, so you can specify an app to handle a particular part of your website.

看起来我们可以通过在details这个数组中调整内容的优先顺序来达到目的。
那到底行不行呢?我们来测测看。

  • 准备
    • https://shaggon.com/apple-app-site-association <– A First
    • https://www.doruby.com/apple-app-site-association <– B First
    • A clean Simulator iPhone 7
    • Installed app A
    • Installed app B
  • 测试


















Device installed A&B Device installed A Only Device installed B Only
A First A Opened A Opened B Opened
B First B Opened A Opened B Opened

结论

就如苹果文档中所说的那样,universal link是存在跳转的优先级的,只需要修改details这个数组中的内容的顺序即可。

DYKit

发表于 2017-09-04

DYKit

CocoaPods 
CocoaPods 
Support 

DYKit是一套使用了ReactiveObjC的系统控件封装库

DYKit将UIkit中的大部分常用组件进行了封装,让这些控件不再使用delegate,datasource等而是可以通过block,RACSignal等形式进行控制,通过链式调用,很多控件从此可以通过一句代码完成。

sample

不需要delegate,datasource。你可以如此简单的创建一个tableView:

1
2
3
4
5
6
7
[self.homeTableView assemblyWithAssemblyBlock:^(UITableViewCell *cell, NSString *text, NSIndexPath *indexPath) {
//这个block充当了cellForRowAtIndexPath的作用
cell.textLabel.text = text;
}];
//设定数据
self.homeTableView.dy_data = @[@"标题1",@"标题2",@"标题3",@"标题4"];
  1. dy_data是一个NSArray的属性。你只能给他绑定发送NSArray的RACSignal.当然你也可以像下面这样直接给他赋值。
    self,homeTableView.dy_data = @[@"标题1",@"标题2",@"标题3",@"标题4"];
  2. dy_data中的每一个元素都会出现在上面那个assemblyWithAssemblyBlock中的第二个参数。你可以修改参数成任意类型,比如model或videModel甚至是NSString。

你可以使用下面的方法来创建不同类型的tableView:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[self.tableView assemblyByReuseIdentifier:@"OneTypeCellByNibTableViewCell" withAssemblyBlock:^(OneTypeCellByNibTableViewCell *cell, User *user, NSIndexPath *indexPath) {
cell.headImageView.image = [UIImage imageNamed:user.img];
cell.headImageView.backgroundColor = user.sex == 0 ? [UIColor purpleColor] : [UIColor blackColor];
cell.nameLabel.text = user.name;
cell.ageLabel.text = user.age;
cell.descLabel.text = user.desc;
}];
User *user1 = [User new];
User *user2 = [User new];
User *user3 = [User new];
user1.id = @"001";
user1.name = @"jack";
user1.img = @"head";
user1.age = @"29";
user1.desc = @"她喜欢黑色";
user1.sex = 0;
user2.id = @"002";
user2.name = @"Pink man";
user2.img = @"head";
user2.age = @"18";
user2.desc = @"白老师得意门生";
user2.sex = 1;
user3.id = @"003";
user3.name = @"MR.white";
user3.img = @"head";
user3.age = @"43";
user3.desc = @"平淡无奇的中学化学老师";
user3.sex = 1;
self.tableView.dy_data = @[user1,user2,user3];
  1. reuseIdentifier参数传入一个复用ID。用来自动注册cell和使用复用cell,可支持nib或class创建的cell。(优先寻找reuseIdentifier命名的xib文件,找到的情况下直接注册nibcell。找不到的情况下会使用reuseIdentifier作为类名的非nib创建cell)

当然你也可以使用下面这些方法来满足不同cell在同一个tableView或者不同的cetion下使用的需求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
指定section和row进行cell设定
@param identifier cell的重用ID(使用cell的类名,可以是xib或者class创建)
@param section 指定section位置
@param row 指定row位置
@param block cellForRowAtIndexPath的block
@return 返回自身,用于链式调用
*/
- (UITableView*) addReuseIdentifier:(NSString *)identifier FromSection:(int)section row:(int)row withAssemblyBlock:(AssemblyBlock)block;
/**
指定section进行cell设定。默认本section下的cell全部按照block内容进行设定
@param identifier cell的重用ID(使用cell的类名,可以是xib或者class创建)
@param section 指定section位置
@param block cellForRowAtIndexPath的block
@return 返回自身,用于链式调用
*/
- (UITableView*) addReuseIdentifier:(NSString *)identifier FromSection:(int)section withAssemblyBlock:(AssemblyBlock)block;
/**
指定row进行cell设定。默认只有一个section
@param identifier cell的重用ID(使用cell的类名,可以是xib或者class创建)
@param row 指定row位置
@param block cellForRowAtIndexPath的block
@return 返回自身,用于链式调用
*/
- (UITableView*) addReuseIdentifier:(NSString *)identifier FromRow:(int)row withAssemblyBlock:(AssemblyBlock)block;
/**
指定具体的indexPath进行cell设定,可选择任意位置
@param identifier cell的重用ID(使用cell的类名,可以是xib或者class创建)
@param slotBlock 用于指定具体条件的block。通过对参数的indexPath进行判断,返回需要的具体位置
@param cellBindBlock cellForRowAtIndexPath的block
@return 返回自身,用于链式调用
*/
- (UITableView*) addReuseIdentifier:(NSString *)identifier FromSlot:(SlotBlock)slotBlock withAssemblyBlock:(AssemblyBlock)cellBindBlock;

代理事件

你可以用这些方法获得你需要的代理事件的Signal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma delegate方法
- (RACSignal*)accessoryButtonTappedForRowWithIndexPathSignal;
- (RACSignal*)didEndDisplayingCellSignal;
- (RACSignal*)didEndDisplayingHeaderViewSignal;
- (RACSignal*)didEndDisplayingFooterViewSignal;
- (RACSignal*)didHighlightRowAtIndexPathSignal;
- (RACSignal*)didUnhighlightRowAtIndexPathSignal;
- (RACSignal*)didSelectRowAtIndexPathSignal;
- (RACSignal*)didDeselectRowAtIndexPathSignal;
- (RACSignal*)didEndEditingRowAtIndexPathSignal;
- (RACSignal*)didUpdateFocusInContextSignal;
- (RACSignal*)performActionSignal;
- (RACSignal*)willBeginEditingRowAtIndexPathSignal;
- (RACSignal*)willDisplayCellSignal;
- (RACSignal*)willDisplayHeaderViewSignal;
- (RACSignal*)willDisplayFooterViewSignal;
#pragma DataSource方法
- (RACSignal*)commitEditingStyleSignal;
- (RACSignal*)moveRowAtIndexPathSignal;

回调方法

你也可以通过传入block的方法来设置tableView的属性。名字和原来的那些一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#pragma 配置用block
- (UITableView*)setHeightForRowAtIndexPath:(CGFloatTableViewIndexPath)block;
- (UITableView*)setEditActionsForRowAtIndexPath:(EditActionsForRowAtIndexPath)block;
- (UITableView*)setShouldHighlightRowAtIndexPath:(BOOLTableViewIndexPath)block;
- (UITableView*)setCanEditRowAtIndexPath:(BOOLTableViewIndexPath)block;
- (UITableView*)setNumberOfRowsInSection:(NSIntegerTableViewIndexPath)block;
//- (void)setCellForRowAtIndexPath:(UITableViewCellTableViewIndexPath)block;
- (UITableView*)setNumberOfSectionsInTableView:(NSIntegerUITableView)block;
- (UITableView*)setTitleForHeaderInSection:(NSStringTableViewNSInteger)block;
- (UITableView*)setTitleForFooterInSection:(NSStringTableViewNSInteger)block;
- (UITableView*)setCanMoveRowAtIndexPath:(BOOLTableViewIndexPath)block;
- (UITableView*)setSectionIndexTitlesForTableView:(SectionIndexTitlesForTableView)block;
- (UITableView*)setSectionForSectionIndexTitle:(NSIntegerUITableViewNSStringNSInteger)block;
- (UITableView*)setHeightForHeaderInSection:(CGFloatTableViewNSInteger)block;
- (UITableView*)setHeightForFooterInSection:(CGFloatTableViewNSInteger)block;
- (UITableView*)setEstimatedHeightForRowAtIndexPath:(CGFloatTableViewIndexPath)block;
- (UITableView*)setEstimatedHeightForHeaderInSection:(CGFloatTableViewNSInteger)block;
- (UITableView*)setEstimatedHeightForFooterInSection:(CGFloatTableViewNSInteger)block;
- (UITableView*)setViewForHeaderInSection:(UIViewTableViewNSInteger)block;
- (UITableView*)setViewForFooterInSection:(UIViewTableViewNSInteger)block;
- (UITableView*)setWillSelectRowAtIndexPath:(NSIndexPathUITableViewNSIndexPath)block;
- (UITableView*)setWillDeselectRowAtIndexPath:(NSIndexPathUITableViewNSIndexPath)block;
- (UITableView*)setEditingStyleForRowAtIndexPath:(UITableViewCellEditingStyleUITableViewNSIndexPath)block;
- (UITableView*)setTitleForDeleteConfirmationButtonForRowAtIndexPath:(NSStringTableViewIndexPath)block;
- (UITableView*)setShouldIndentWhileEditingRowAtIndexPath:(BOOLTableViewIndexPath)block;
- (UITableView*)setTargetIndexPathForMoveFromRowAtIndexPath:(NSIndexPathUITableViewNSIndexPathNSIndexPath)block;
- (UITableView*)setIndentationLevelForRowAtIndexPath:(NSIntegerUITableViewNSIndexPath)block;
- (UITableView*)setShouldShowMenuForRowAtIndexPath:(BOOLTableViewIndexPath)block;
- (UITableView*)setCanPerformAction:(BOOLUITableViewSELNSIndexPath)block;
- (UITableView*)setCanFocusRowAtIndexPath:(BOOLTableViewIndexPath)block;
- (UITableView*)setShouldUpdateFocusInContext:(BOOLUITableViewFocusUpdateContext)block;
- (UITableView*)setIndexPathForPreferredFocusedViewInTableView:(NSIndexPathUITableView)block;

安装

CocoaPods

  1. 在 Podfile 中添加 pod 'DYKit'。
  2. 执行 pod install 或 pod update。
  3. 导入 \”DYKit.h\”。

将来

  1. 实现UIcollectionView的封装
  2. 实现UITextView的封装

系统要求

该项目最低支持 iOS 8.0。

许可证

DYKit 使用 MIT 许可证,详情见 LICENSE 文件。

shaggon

shaggon

分享技术

2 日志
1 标签
GitHub 微博
© 2018 shaggon
由 Hexo 强力驱动
主题 - NexT.Muse