文档章节

【iOS开发】仿微信分享功能

hejunbinlan
 hejunbinlan
发布于 2016/11/01 17:12
字数 2329
阅读 60
收藏 1

目标

本篇文章讲的是我做的一个仿微信分享到朋友圈的功能。
事先声明,楼主并不知道微信的分享具体是怎么实现的,只是按照楼主自己的想法做了一个。而且,比较简陋。
这篇文章主要是我上一篇文章的一个延伸。很多知识点在上一篇文章讲过了,这里就不再重复了。建议先看了上一篇文章再来看这篇文章。
入口:【iOS开发】打开另一个APP(URL Schemes与openURL)

实现过程

  • MyApp使用带了参数的url打开WXApp(微信APP)
  • WXApp在handleOpenURL回调中获取MyApp带过来的url
  • WXApp根据url的参数来跳转到朋友圈,并且给朋友圈分享内容。
  • 5秒之后,弹出alertView,选择是留在微信还是返回MyApp。
  • 根据用户的选择执行相应的动作。

创建MyApp工程并做相应的设置

  • 创建一个名为“MyApp”的工程。这个工程是“我的APP”,是用来做分享用的。
    在Main.storyboard中添加一个button(分享到微信朋友圈),点击这个button就执行分享的方法。

    创建MyApp工程并添加button事件

- (IBAction)sharedToPengYouQuan:(UIButton *)sender { 
    //创建一个url,这个url就是WXApp的url,记得加上://
    NSURL *url = [NSURL URLWithString:@"weixin://dl/moments?title=hello&content=helloworld&urlschemes=shixueqian"];

    //先判断是否能打开该url
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        //打开url
        [[UIApplication sharedApplication] openURL:url];
    } else {
        //给个提示或者做点别的事情
        NSLog(@"打不开weixin://。请检查有没有设置URL Schemes白名单或者有没有安装带有weixin://的应用");
    }   
}

这个方法只是创建了一个url,并且openURL。下面解析一下这个url的具体参数,

  • 使用weixin://这个URL Scheme来打开WXApp。
  • 使用weixin://dl/moments这个绝对路径来判断是否要跳转到朋友圈。
  • 使用title=hello&content=helloworld这两个参数来设置分享的内容。
  • 使用urlschemes=shixueqian来从WXApp跳转回MyApp。
  • 因为我们需要在分享完之后需要从WXApp跳转回来,所以需要设置URL Schemes,来让WXApp打开MyApp。
    步骤:选中MyApp工程->Info->URL Types->点击“+”->在URL Schemes栏填上 shixueqian

设置URL Schemes

这样WXApp就可以通过shixueqian://来打开MyApp了。

  • 设置URL Schemes白名单
    因为我们点击button的时候使用了canOpenURL:方法,故在iOS9环境需要设置URL Schemes白名单。
    步骤:点击info.plist文件->右键->Open As->Source Code->添加下面的代码
      <key>LSApplicationQueriesSchemes</key>
      <array>
          <string>weixin</string>
      </array>

设置URL Schemes白名单

OK,我们的MyApp已经完成了。

创建WXApp工程并做相应的设置。

  • 创建一个名为“WXApp”的工程并在Main.storyboard中加一个label。表明这个是WXApp的主界面。

    创建WXApp工程并在主界面加个label

  • 设置URL Schemes。
    因为我们需要被MyApp打开的,所以需要设置URL Schemes来让别的APP打开。
    步骤:选中MyApp工程->Info->URL Types->点击“+”->在URL Schemes栏填上 weixin

设置URL Schemes

备注:
在WXApp里面是不需要设置MyApp为URL Schemes白名单的。
以真正的微信为例,微信分享和微信登录的开发者这么多,有这么多软件用到了这些功能,微信事先并不知道它们的URL Schemes。就算知道了,白名单最多只有50个,是远远不够的。所以是不会调用canOpenURL:方法来判断是否能打开的。
那不先判断一下能否打开,假如微信打不开MyApp,苹果会不会拒绝微信上架呢?
如果我是微信,我会采用了另外的方法来判断。
我们知道,使用微信的分享功能必须要在微信开放平台上注册你的APP,微信开放平台会生成一个ID,你必须要设置微信给你的URL Schemes。假如你不设置,微信SDK就会报错。
在这个前提下,有两种获取MyApp的URL Schemes的方式。

  • 方式一:MyApp使用分享功能打开微信App的时候,会把bundleID传过来的(回调方法中的sourceApplication),通过这个bundleID就可以从服务器上查到微信给你的URL Schemes。
  • 方式二:在打开微信APP的url中将MyApp的URL Schemes传过来。(微信应该会对这个URL Schemes进行验证的,我就不脑洞了)

我们这个demo中用的是方式二,在url中当做参数将URL Schemes传过来。

  • 创建SQPengYouQuanController
    由于我们要跳转到朋友圈,所以要设置朋友圈控制器。
    创建SQPengYouQuanController,使用的是xib方式。
    在xib上加了几个label,并且把titleLabel和contentLabel作为SQPengYouQuanController的属性。这两个label的内容是通过MyApp传过来的url中的参数来设置的。

    设置朋友圈界面

  • 在SQPengYouQuanController.h中设置一个url属性
    这个url是MyApp传过来,用来设置titleLabel和contentLabel,并且设置返回MyApp。

//  SQPengYouQuanController.h
//  WXApp
//
//  Created by 石学谦 on 16/7/17.
//  Copyright © 2016年 shixueqian. All rights reserved.
#import <UIKit/UIKit.h>
@interface SQPengYouQuanController : UIViewController

//其他APP传过来的url,用来设置titleLabel和contentLabel,并且设置返回别的APP。
@property (nonatomic, strong) NSURL *url;

@end
  • 在SQPengYouQuanController.m中进行分享后的设置
    url传过来,我们可以利用url里面的参数对两个label赋值。并且根据url传过来的URL Schemes来跳转回MyApp。
@implementation SQPengYouQuanController

- (void)viewDidLoad {
    [super viewDidLoad];
    //设置分享后的内容
    [self displayWithURL:self.url];
}

//设置分享后的内容
- (void)displayWithURL:(NSURL *)url {

    //获取url中的参数,转化为字典
    NSDictionary *params = [self getParamsWithURL:url];
    NSLog(@"dict=====\n%@",params);

    //给label设置值
    self.titleLabel.text = params[@"title"];
    self.contentLabel.text = params[@"content"];

    //延迟5秒再弹出alertView
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //创建alertViewController
        UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"分享后的操作" message:@"是否返回原应用?" preferredStyle:UIAlertControllerStyleAlert];

        //返回按钮
        UIAlertAction *backAction = [UIAlertAction actionWithTitle:@"返回" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            //从字典中取出URL Schemes
            NSString *backURLString = [NSString stringWithFormat:@"%@://",params[@"urlschemes"]];
            NSURL *backURL = [NSURL URLWithString:backURLString];
            //跳转回MyApp
            [[UIApplication sharedApplication] openURL:backURL];
        }];
        [controller addAction:backAction];

        //留在微信按钮
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"留在微信" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSLog(@"留在微信");
        }];
        [controller addAction:cancelAction];

        //展示alertView
        [self presentViewController:controller animated:YES completion:nil];        
    });
}

//将url里面的参数转换成字典
- (NSDictionary *)getParamsWithURL:(NSURL *)url {

    //query是?后面的参数,在这个demo中,指的是title=hello&content=helloworld&urlschemes=shixueqian
    NSString *query = url.query;

    //进行字符串的拆分,通过&来拆分,把每个参数分开
    NSArray *subArray = [query componentsSeparatedByString:@"&"];
    //把subArray转换为字典
    //tempDic中存放一个URL中转换的键值对
    NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];

    for (int i = 0 ; i < subArray.count ; i++) {
        //通过“=”拆分键和值
        NSArray *dicArray = [subArray[i] componentsSeparatedByString:@"="]
        ;
        //给字典加入元素,=前面为key,后面为value
        [tempDic setObject:dicArray[1] forKey:dicArray[0]];
    }
    //返回转换后的字典
    return tempDic ;
}

@end

大概分析一下这段代码:

  • viewDidLoad:中调用了displayWithURL :方法
  • displayWithURL :方法做了3件事:
    从URL中获取到参数,并转换成字典dict
    将字典dict中的title和content的值赋给titleLabel和contentLabel
    延迟5秒后弹出alertView,选择回到MyApp或者留在WXApp
  • getParamsWithURL:方法是将url里面的参数转换成字典,方便后面的处理

在WXApp的appDelegete.m中做跳转的处理

我们知道,在MyApp通过URL Schemes打开WXApp的时候,会调用appDelegate中的handleOpenURL:回调的。所以我们要在这个回调中获取到MyApp传过来的url,并且判断是否需要跳转到朋友圈。

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {

    NSLog(@"url====%@\n sourceApplication====%@\n annotation===%@",url,sourceApplication,annotation);

    //判断是否要跳转到朋友圈
    if ([url.absoluteString hasPrefix:@"weixin://dl/moments"]) {
        //创建SQPengYouQuanController控制器
        SQPengYouQuanController *controller = [[SQPengYouQuanController alloc] initWithNibName:@"SQPengYouQuanController" bundle:nil];
        //给url赋值
        controller.url = url;

        //找出当前的控制器
        UIViewController *rootViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
        //跳转到朋友圈
        [rootViewController presentViewController:controller animated:YES completion:nil];

    } else {
        //不是跳转到朋友圈
    }
    return YES;
}
@end

分析一下这段代码:

  • 先判断是否要跳转到朋友圈,如果是weixin://dl/moments前缀的就跳转,否则不跳转。
  • 创建SQPengYouQuanController控制器,并将MyApp传过来的url赋值给SQPengYouQuanController中的url
  • 找出当前的rootViewController,并跳转到朋友圈

好了,万里长征只差一步,运行。

  • 运行WXApp,会展示WXApp的主界面

运行WXApp

  • 运行MyApp

运行MyApp

  • 点击MyApp中的“分享到微信朋友圈”按钮,会跳转到WXAPP的朋友圈中,而且标题和内容都有了

点击MyApp中的“分享到微信朋友圈”按钮

  • 5秒过后,会弹出一个提示框

5秒过后,会弹出一个提示框

  • 点击“返回”后,会跳转回MyApp

会跳转回MyApp

好了,大功告成。

备注:handleOpenURL回调中这样处理是有bug的,不知道大家发现了没?我就懒得处理咯,哈哈。

参考

本章的Demo已经上传到GitHub上面了。https://github.com/shixueqian/-IOS-
详解URL的组成
网络基础教程-http中url的组成和首部字段详解
Objective-C中把URL请求的参数转换为字典
非常有深度的讲解URL Shemes的文章:URL Schemes使用详解
一些著名APP的URL Schemes:苹果app(iOS app)的URL schemes

谦言万语

别打赏,我要的是喜欢。


 

文/谦言忘语(简书作者)
原文链接:http://www.jianshu.com/p/43ece5298eb5
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

本文转载自:http://www.jianshu.com/p/43ece5298eb5

hejunbinlan
粉丝 41
博文 596
码字总数 21569
作品 0
浦东
高级程序员
私信 提问
加载中

评论(1)

小码爱大牛
小码爱大牛
你好,我是深圳一家以家居安防为核心的智能家居公司的HR在招聘一位iOS开发架构师兼leader。不知道您自己或者身边同事朋友有没有在看工作机会的呢?如果感兴趣可以发简历到3288771685@qq.com或者加QQ。
【iOS开发】canOpenURL: failed for URL

如图是在我启动一个 Xcode 7 + iOS 9 的 App 之后,控制台的输出。 这在 Xcode 6.4 + iOS 8 时,是不会有的情况,原因是【为了强制增强数据访问安全, iOS9 默认会把所有从 、 、 发出的 HT...

kyxu
2015/09/18
0
0
微信小程序开发之页面分享 onShareAppMessage 分享参数用处

今天下午突然听到群里有人说微信小程序工具更新了,文档也更新了不少内容. 顾不上吃冬至的饺子.我就冲进来了. 先说分享功能,目前真机尚不能调试.开发工具上可以看看效果.后续还会更新. Page(...

qq_31383345
2016/12/21
0
0
亿万级仿微信仿陌陌社交app源码出售转让(接受定制开发)

亿万级仿微信仿陌陌社交app源码出售转让(接受定制开发) 分享多样化:除了文字和多图分享,支持视频分享,还有移动互联必备的地理位置玩法,让分享更加有趣 像微信一样聊天:加强了聊天的扩展...

一只驴
2017/07/09
207
0
手机直播可二次开发、萌颜、连麦、弹幕,首选云豹直播

云豹直播(0538-8270220)作为业内领先的直播程序开发商,全面分析市场趋势,强势推出最符合市场需求的直播营销方案----云豹直播系统。 云豹直播是国内第一家专业开发视频直播程序软件以及出...

泰安云豹直播
2016/07/18
9
0
关于微信的那点帖。。。。。。(各种实例)

照惯例发帖先吐槽一下:最近看到大家发防微信功能特别的多,所以就汇总了一下,看看大家还有什么其他方面的汇总需求,回复我噢,均可满足。。。。。 (ps:有些帖子由于主观、客观还有神马原因...

程序袁_绪龙
2015/04/01
233
0

没有更多内容

加载失败,请刷新页面

加载更多

uni app 零基础小白到项目实战

$emit 子组件传给父组件$ref 父组件操作子组件 公用模板 uni-app全局变量的几种实现方法 const websiteUrl = 'http'const now = Date.now || function() { return new Date().getTime......

达达前端小酒馆
15分钟前
4
0
Tomcat是如何实现异步Servlet的

前言 通过我之前的Tomcat系列文章,相信看我博客的同学对Tomcat应该有一个比较清晰的了解了,在前几篇博客我们讨论了Tomcat在SpringBoot框架中是如何启动的,讨论了Tomcat的内部组件是如何设...

木木匠
39分钟前
14
0
mysql中间件分享(Mysql-prxoy,Atlas,DBProxy,Amoeba,cobar,TDDL)

hello 各位小伙伴大家好,我是小栈君,这期我们分享关于mysql中间件的研究,也就是数据层的读写分离和负载均衡,希望能够在实际的应用中能够帮助到各位小伙伴。 下期我们将继续分享go语言的系...

IT干货栈
今天
10
0
OSChina 周一乱弹 —— 人生,还真是到处是意外

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @这次装个文艺青年吧 :#今日歌曲推荐# 分享lil peep的单曲《High School》 《High School》- lil peep 手机党少年们想听歌,请使劲儿戳(这里...

小小编辑
今天
611
10
Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部