WFC-LinkedME / LinkedME-iOS-Deep-Linking-Demo

LinkedME是国内首家企业级深度链接服务平台,致力于帮助App提高用户增长和流量变现。LinkedME采用Deep Linking,Deferred Deep Linking,Contextual Deep Linking, Machine Learning等技术,为移动产品提供全新的商业价值。
http://www.linkedme.cc
MIT License
35 stars 5 forks source link

LinkedME iOS 集成文档

CI Status Version License Platform

进入官网查看详细文档

接入方法

使用 CocoaPods

1.编辑Podfile文件并添加以下代码

pod 'LinkedME_LinkPage'

2.运行 pod install

3.从现在开始使用 .xcworkspace 打开项目,而不是 .xcodeproj

提示:如果提示[!] Unable to find a pod with name, author, summary, or description matching ` LinkedME_LinkPage`

解决方法就是Finder前往资源库去删除缓存中的search_index.json

执行:rm -rf ~/Library/Caches/CocoaPods/search_index.json 再重新search/install/update

手动导入

1.获取SDK,下载Demo, LinkedME_DEMO文件夹下的LinkedME_iOS.framework文件是SDK的文件。(SDK下载地址

2.依赖Frameworks:

CoreSpotlight.framework (status:Optional) SystemConfiguration.framework Security.framework AdSupport.framework CoreTelephony.framework

注意事项:CoreSpotlight.framework必须标记为可选 导入AdSupport.frame但是app中没有广告审核问题 spotlight warning

1.注册并添加应用

1.1注册账号

LinkedME账号通用于我们提供的所有产品,登录官方网站进行注册,并登陆系统。

1.2 开通使用

注册成功之后,即可登录使用。

1.3 创建应用

成功登录后台之后,可点击+按钮创建应用。 创建app

输入APP名字之后,点击“创建APP”完成创建。可以到后台导航栏设置->应用中查看应用相关信息。 创建app

1.4 应用设置

点击设置可以对应用进行设置。 设置app

1 点击修改应用名字

2 点击修改应用Logo

3 点击删除应用

注意事项:如果误删应用后,请发邮件到support@linkedme.cc。

1.5 设置应用

设置应用

1 勾选“是否有iOS应用”项。

2 URI Scheme,点击输入框输入您的iOS应用的URI Scheme协议,示例:linkedmedemo

3 下载地址,可以是AppStore上的下载地址,也可以自定义

4 Universal Links为iOS官方深度链接标准,iOS 9.0以上系统支持,可实现应用间无缝跳转。访问苹果开发者网站,在Appid中查看Bundle ID和Prefix的值

bundle id

2.1 SDK&Demo(简述)

文件名 描述
LinkedME_iOS.framework LinkedME SDK
DetailViewController Demo详情页-webView加载html网页
DemoViewController 生成短链,展示生成锻炼的必要参数
DefaultData 参数默认必要参数

3.导入LinkedME iOS SDK(必须实现)*

把Demo工程中的LinkedME_iOS.framework,导入工程中。

4. 添加系统Framework*

1 CoreSpotlight.framework (status:Optional)

2 SystemConfiguration.framework

3 Security.framework

注意事项:CoreSpotlight.framework必须标记为可选 spotlight warning

5.注册URL Scheme(推荐/可选)

1 打开info.plist

2 找到URL Types(如果没有就右键add row添加一个)

3 添加"you app"(你的app的唯一标识字符串) urltypes set up

5.1 添加Universal Linking支持 (仅支持iOS 9)*

1 在左侧导航器中点击您的项目

2 选择'Capabilities'标签

3 打开'Associated Domains'开关

4 添加applinks:lkme.cc和applinks:www.lkme.cc Associated Domains set up

5.2 添加linkedme_key

1 打开info.plist文件

2 在列表中点击右键选择add row添加一个分组

3 创建一个新的item名称为linkedme_key类型为Dictionary

4 在linkedme_key新增一个字符串类型的item, live字段,到后台“设置”->“应用”中进行查看

lmkey set up

6.代码集成 - 设置AppDelegate - 解析深度链接跳转参数*

1 在AppDelegate中引入头文件

import <LinkedME_iOS/LinkedME.h>

2 在Appdelegate里注册ViewController

 6.1配置注册viewController并设置跳转方式

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.'
    //初始化及实例
    LinkedME* linkedme = [LinkedME getInstance];

    //    //注册需要跳转的viewController
    UIStoryboard * storyBoard=[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    DetailViewController  *dvc=[storyBoard instantiateViewControllerWithIdentifier:@"detailView"];

    //[自动跳转]如果使用自动跳转需要注册viewController
    //    [linkedme registerDeepLinkController:featureVC forKey:@"LMFeatureViewController"];

    //获取跳转参数
    [linkedme initSessionWithLaunchOptions:launchOptions automaticallyDisplayDeepLinkController:NO deepLinkHandler:^(NSDictionary* params, NSError* error) {
        if (!error) {
            //防止传递参数出错取不到数据,导致App崩溃这里一定要用try catch
            @try {
            NSLog(@"LinkedME finished init with params = %@",[params description]);
            //获取标题
            NSString *title = [params objectForKey:@"$og_title"];
            NSString *tag = params[@"$control"][@"View"];

                if (title.length >0 && tag.length >0) {

                    //[自动跳转]使用自动跳转
                    //SDK提供的跳转方法
                    /**
                     *  pushViewController : 类名
                     *  storyBoardID : 需要跳转的页面的storyBoardID
                     *  animated : 是否开启动画
                     *  customValue : 传参
                     *
                     *warning  需要在被跳转页中实现次方法 - (void)configureControlWithData:(NSDictionary *)data;
                     */

//                    [LinkedME pushViewController:title storyBoardID:@"detailView" animated:YES customValue:@{@"tag":tag} completion:^{
////
//                    }];

                    //自定义跳转
                    dvc.openUrl = params[@"$control"][@"ViewId"];
                    [[LinkedME getViewController] showViewController:dvc sender:nil];

                }

                            } @catch (NSException *exception) {

                            } @finally {

                            }

        } else {
            NSLog(@"LinkedME failed init: %@", error);
        }
    }];
    return YES;
}

Swift

1 xxxx-Bridging-Header.h中导入头文件 #import <LinkedME_iOS/LinkedME.h>

2 在Appdelegate里注册ViewController

 2.1配置注册vc设置及跳转方式

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.

        let linkedme = LinkedME.getInstance();
        //是否开启Debug模式
        //linkedme.setDebug();
        let storyBoard = UIStoryboard().instantiateViewControllerWithIdentifier("detailView");
        linkedme.registerDeepLinkController(storyBoard, forKey: "detailView");

        //获取跳转参数
        linkedme.initSessionWithLaunchOptions(launchOptions, automaticallyDisplayDeepLinkController: false) { (params, error) in
            if(error != nil){
                print("LinkedME finished init with params\(params.description)");
                let title = params["$og_title"];
                let tag = params["$control"]!["ViewId"];

                if (title!.isEqualToString("DetailViewController")){

                    LinkedME.pushViewController(title as! String, storyBoardID: "detailView", animated: true, customValue: tag as! [AnyObject], completion: {

                    });
                }
            }else{
                print(error);
            }
        }

        return true
    }
实现自定义跳转必须注册ViewController遵循LMDeepLinkingController协议
并实现 - (void)configureControlWithData:(NSDictionary *)data方法

7.添加URLScheme和Uniiversal LinKing支持

 在Appdelegate中实现下列方法

OC

- (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation{
    //判断是否是通过LinkedME的UrlScheme唤起App
    if ([[url description] rangeOfString:@"click_id"].location != NSNotFound) {
        return [[LinkedME getInstance] handleDeepLink:url];
    }

    return YES;
}
//Universal Links 通用链接实现深度链接技术
- (BOOL)application:(UIApplication*)application continueUserActivity:(NSUserActivity*)userActivity restorationHandler:(void (^)(NSArray*))restorationHandler{

    //判断是否是通过LinkedME的Universal Links唤起App
    if ([[userActivity.webpageURL description] rangeOfString:@"lkme.cc"].location != NSNotFound) {
        return  [[LinkedME getInstance] continueUserActivity:userActivity];
    }

    return YES;
}
//URI Scheme 实现深度链接技术
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options{
    NSLog(@"opened app from URL %@", [url description]);

    //判断是否是通过LinkedME的UrlScheme唤起App
    if ([[url description] rangeOfString:@"click_id"].location != NSNotFound) {
        return [[LinkedME getInstance] handleDeepLink:url];
    }
    return YES;
}

Swift

//URI Scheme 实现深度链接技术
 func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    //判断是否是通过LinkedME的UrlScheme唤起App
        if url.absoluteString.componentsSeparatedByString("click_id").count > 1 {
            return LinkedME.getInstance().handleDeepLink(url);
        }

    }
 //Universal Links 通用链接实现深度链接技术
    func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
        //判断是否是通过LinkedME的Universal Links唤起App
        if url.absoluteString.componentsSeparatedByString("lkme.cc").count > 1 {
            return LinkedME.getInstance().continueUserActivity(userActivity);
        }
    }
    //URI Scheme 实现深度链接技术
    func  application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
        //判断是否是通过LinkedME的UrlScheme唤起App
        if url.absoluteString.componentsSeparatedByString("click_id").count > 1 {
            return LinkedME.getInstance().handleDeepLink(url);
        }
    }

创建深度连接

创建深度链接提供两种方式

1 使用iOS/Android SDK创建 2 使用WEB SDK创建

注:附录中详解采用哪种方式创建深度链接

//创建短链
-(void)addPara{
    self.linkedUniversalObject = [[LMUniversalObject alloc] init];
    self.linkedUniversalObject.title = title;//标题
    LMLinkProperties *linkProperties = [[LMLinkProperties alloc] init];
    linkProperties.channel = @"";//渠道(微信,微博,QQ,等...)
    linkProperties.feature = @"Share Wechat1";//特点
    linkProperties.tags=@[@"LinkedME",@"Demo"];//标签
    linkProperties.stage = @"Live";//阶段

    [linkProperties addControlParam:@"View" withValue:arr[page][@"url"]];//页面唯一标识
    [linkProperties addControlParam:@"LinkedME" withValue:@"Demo"];//Demo标识

    [self.linkedUniversalObject getShortUrlWithLinkProperties:linkProperties andCallback:^(NSString *url, NSError *err) {
        if (url) {
            NSLog(@"[LinkedME Info] SDK creates the url is:%@", url);
            //
            [H5_LIVE_URL stringByAppendingString:arr[page][@"form"]];
            [H5_LIVE_URL stringByAppendingString:@"?linkedme="];

            H5_LIVE_URL = [NSString stringWithFormat:@"https://www.linkedme.cc/h5/%@?linkedme=",arr[page][@"form"]];
            _LINKEDME_SHORT_URL = [H5_LIVE_URL stringByAppendingString:url];

        } else {
            _LINKEDME_SHORT_URL = H5_LIVE_URL;
        }
    }];
}

Debug模式

在Debug模式下会打印日志

OC

[linkedme setDebug];

Swift

linkedme.setDebug();

测试模式

在后台(Dashboard)中-设置-测试-添加测试设备

OC

通过[LinkedME getTestID]获取设备ID,去后台中添加设备

S wift

通过LinkedME.getTestID()获取设备ID,去后台中添加设备

6.Spotlight

6.1创建Spotlight索引

OC

[[LinkedME getInstance] createDiscoverableContentWithTitle:@"LinkedME 国内第一家企业级深度链接"
                                                   description:@"让APP不再是信息孤岛!"
                                                  thumbnailUrl:[NSURL URLWithString:@"http://7xq8b0.com1.z0.glb.clouddn.com/logo.png"]
                                                    linkParams:dict
                                                          type:@""
                                             publiclyIndexable:NO keywords:set5
                                                expirationDate:nil
                                           spotlightIdentifier:@"bbcc"
                                             spotlightCallback:^(NSString *url, NSString *spotlightIdentifier, NSError *error) {

    }];

Swift

    LinkedME.getInstance().createDiscoverableContentWithTitle("LinkedME 国内第一家企业级深度链接",
                                                                  description: "让APP不再是信息孤岛!",
                                                                  thumbnailUrl: NSURL.init(string: "http://7xq8b0.com1.z0.glb.clouddn.com/logo.png"),
                                                                  linkParams: dic,
                                                                  type: nil,
                                                                  publiclyIndexable: false,
                                                                  keywords: keyWord as NSSet as Set<NSObject>,
                                                                  expirationDate: nil,
                                                                  spotlightIdentifier: "linkedme") { (url, spotlightID, error) in

        }

设置关键字

OC

    NSSet *keyWord = [NSSet setWithObjects:@"linkedme", nil];

Swift

    let keyWord = NSSet.init(array: ["linkedme","hellolkm"])

需要传递的参数

OC

    NSSet *set5 = [NSSet    setWithObjects:@"linkedme",@"linked",@"深度链接", nil];

Swift

    let dic = ["url":"http://linkedme.cc"]

关键字详解

title 标题
description 描述
publiclyIndexable 是否公开
type 类型
thumbnailUrl 缩略图Url
keywords 关键字
userInfo 用户详情
expirationDate 失效日期,设置失效日期会自动删除索引
identifier 标志符
callback 回调
spotlightCallback Spotlight回掉

6.2删除索引

6.2.1删除所有索引

OC


[LinkedME removeAllSearchItems];

Swift

     LinkedME.removeAllSearchItems();

6.2.2通过spotlightIdentifier删除索引

OC


[LinkedME removeSearchItemWith:@[@"linkedme"]];

Swift


LinkedME.removeSearchItemWith(["linkedme"])

附录:

1.实现SDK提供的跳转方法(传参)

reg view0 reg view

2.什么时候使用WEB SDK 创建深度链接

使用WEB SDK生成深度链接

如下图这种类型有自己的wap站同时有自己的app并且wap站和app的所有页面都是一一对应的,一般如(新闻资讯类,电商类,直播类等),这种方式的app我们建议使用WEB SDK(js)生产深度链接,客户端仅用于解析深度链接。 注:(也可以使用iOS/Android SDK生成深度链接)

ctoutiao

3.什么时候使用iOS/Android SDK 创建深度链接

使用iOS/Android SDK生成深度链接

如下图这种类型,一般是分享活动或者一个游戏房间号,一般没有wap站点的app采用这种方式生成深度链接,再通过js把深度链接放到打开按钮下。

invate

常见问题

YOU+

常见问题
Q: 为什么点击按钮可以直接从微信唤起app?
A: 使用Universal Link技术,可以通过链接直接唤起app。
Q: 为什么右上角会出现lkme.cc?
A: 因为使用了苹果的Universal Link技术打开App。
Q: 可以取消显示么?
A: 不可以,因为这是系统级的,无法控制。
Q: 点击了右上角的lkme.cc为什么出现了下拉点击打开的提示?
A: 当用户点击lkme.cc会在safari中打开链接,如果不点击打开按钮Universal Link会失效,只有再次点击打开按钮,Universal Link才会恢复。
Q: 如果用户没有安装app会怎么样?
A: 点击前往App store下载下载完成后,打开app会跳转到当前分享页面。
Q: 如果没有点击前往App store下载自己去App store搜索下载,下载完成后可以跳转到分享页吗?
A: 不可以,只有点击前往App store下载按钮才会记录浏览器指纹信息,用于匹配跳转指定页,如果没有点击按钮就不会记录信息。

License

LinkedME_iOS is available under the MIT license. See the LICENSE file for more info.