APP中需要将文件分享给QQ和微信好友,常用下面这两种方式。
1、使用系统的UIActivityViewController类发送
2、使用QQ和微信的API分享
UIActivityViewController分享的样式如下:
下面主要一下分享文件到QQ和微信好友如何实现
[API文档]
QQ互联
https://wiki.connect.qq.com/
微信开放平台
https://open.weixin.qq.com
[开发信息编辑]
URL Schema填写QQ
+转化成十六进制的App ID
(附上一个转换网址),转换后的App ID不足八位则前面补0凑齐。
QQ互联

微信开放平台

若公司有多个app,这里设置Universal Links时需要用path区分. 比如:
https://www.jadinec.com/jiding/
https://www.jadinec.com/jisu/
[Universal Links]
QQ SDK版本V3.3.6、微信SDK版本V1.8.6.1之后,接入SDK后应用中需要处理Universal Links拉起APP功能。
不处理Universal Links时,微信还能正常分享,但QQ分享时会报错“设备未授权 (错误码:25105)”。
创建并上传apple-app-site-association文件到服务器
创建一个名为
apple-app-site-association
的文件,没有后缀,但是内容是json
格式。apps
必须设置为[]
,appID的结构为TeamID.bundleID
,其中 Team ID 在第一步已经获取到了,bundleID 可以设置唯一ID也可以设置通配符ID,关键就是Bundle ID是否设置了Associated Domains Enable
。
上传时的MINI TYPE
一定是application/json
。上传到服务器的根目录下或者.well-known目录下,且能通过网址https://<fully qualified domain>/apple-app-site-association
或者https://<fully qualified domain>/.well-known/apple-app-site-association
访问这个文件,不论是否是下载还是直接在浏览器中能直接看到文件内容。
appID的格式是Team ID.Bundle ID,其中Team ID可以登录开发网站(https://developer.apple.com),点击App IDS从列表进入详情查看(如图)。
单个APP时配置:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "CBQFB991WG.com.maojitech.jiding",
"paths": ["*","/qq_conn/101888113/*"]
}
]
}
}
多个APP时配置:
paths中第一个对象是微信的path, 第二个是qq的path
{
"applinks": {
"apps": [],
"details": [
{
"appID": "CBQFB991WG.com.maojitech.jiding",
"paths": ["/jiding/*","/qq_conn/1019489322/*"]
},
{
"appID": "CBQFB991WG.com.maojitech.jisu",
"paths": ["/jisu/*","/qq_conn/101971011/*"]
}
]
}
}
[代码处理]
详细的集成可以去看集成文档,这里用部分代码说明一下操作。
先添加Associated Domains
AppDelegate
#import "AppDelegate.h"
#import <TencentOpenAPI/TencentOAuth.h>
#import "WXApi.h"
static NSString *TencentAppId = @"101880000";
static NSString *JBSWeixinAppId = @"wx635f2582ac160000";
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
// QQ分享
[[TencentOAuth alloc] initWithAppId:TencentAppId andDelegate:nil];
// 微信分享
[WXApi registerApp:JBSWeixinAppId withDescription:@"甲丁"];
}
#pragma mark - QQ分享
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSString *string =[url absoluteString];
if ([string hasPrefix:JBSWeixinAppId]){
return [WXApi handleOpenURL:url delegate:self];
}else if ([string hasPrefix:TencentAppId]){
return[TencentOAuth HandleOpenURL:url];
}
return NO;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
NSString *string =[url absoluteString];
if ([string hasPrefix:JBSWeixinAppId]){
return [WXApi handleOpenURL:url delegate:self];
}else if ([string hasPrefix:TencentAppId]){
return[TencentOAuth HandleOpenURL:url];
}
return NO;
}
- (void)onReq:(BaseReq *)req {
}
- (void)onResp:(BaseResp *)resp {
if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
switch (resp.errCode) {
case WXSuccess:
// 分享成功
break;
case WXErrCodeUserCancel:
// 用户取消分享
break;
default:
// 分享失败
break;
}
}
}
@end
QQ的SDK分享文件到好友现在实现不了,这里采用新闻的方式在分享。
//QQ分享
#import <TencentOpenAPI/QQApiInterfaceObject.h>
#import <TencentOpenAPI/TencentOAuth.h>
#import <TencentOpenAPI/QQApiInterface.h>
@weakify(self);
self.rm_navgationBar = [RMNavigationBar navWithTitle:_fileName rightItem:@"qrCode_Share" rightAction:^{
@strongify(self);
// 分享
IWShareFileViewController *share = [IWShareFileViewController initFromXib];
// share.modalPresentationStyle = UIModalPresentationFullScreen;
share.modalPresentationStyle = UIModalPresentationOverCurrentContext;
share.tapShareBlock = ^(NSInteger tag) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
if (tag == 1000) { // QQ
[self tencentShare];
} else if (tag == 1001) { // 微信
[self shareWeChatLink];
}
});
};
[self presentViewController:share animated:NO completion:nil];
} backAction:^{
@strongify(self);
[self.navigationController popViewControllerAnimated:YES];
}];
/// 文件 分享到QQ
- (void)tencentShare {
NSString *link = _url?:@"";
NSString *title = _fileName?:@"";
//NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString:link]];
//NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3471770554,1562873257&fm=26&gp=0.jpg"]];
dispatch_async(dispatch_get_main_queue(), ^{
if (![TencentOAuth iphoneQQInstalled]) {
// [self showAlert:@"检查到您没有安装腾讯QQ,请先安装QQ再分享。"];
[MBProgressHUD showError:@"检查到您没有安装腾讯QQ,请先安装QQ再分享。"];
} else {
/*
NSURL *newsUrl = [NSURL URLWithString:[link stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
// QQ无法直接发送文件
QQApiFileObject *newsObj = [QQApiFileObject objectWithData:fileData
previewImageData:nil
title:title
description:title];
newsObj.fileName = title;
[newsObj setCflag:kQQAPICtrlFlagQZoneShareOnStart];
*/
// 使用网络连接的方式分享文件
NSString *imgName = @"";
if ([title containsString:@".xlsm"] || [title containsString:@".xls"] || [title containsString:@".XLSM"] || [title containsString:@".XLS"]) {
imgName = @"Microsoft-Excel";
} else if ([title containsString:@".docx"] || [title containsString:@".doc"] || [title containsString:@".DOCX"] || [title containsString:@".DOC"]) {
imgName = @"Microsoft-WORD";
} else if ([title containsString:@".pptx"] || [title containsString:@".ppt"] || [title containsString:@".PPTX"] || [title containsString:@".PPT"]) {
imgName = @"Microsoft-PPT";
} else if ([title containsString:@".pdf"] || [title containsString:@".PDF"]) {
imgName = @"Microsoft-pdf";
}
NSData *imageData;
if ([imgName isEqualToString:@""]) {
} else {
UIImage *image = [UIImage imageNamed:imgName];
imageData = UIImagePNGRepresentation(image);
}
// QQApiURLObject *newsObj = [QQApiURLObject objectWithURL:[NSURL URLWithString:link] title:title description:@"" previewImageData:imageData targetContentType:QQApiURLTargetTypeNews];
// [newsObj setCflag:kQQAPICtrlFlagQQShare];
QQApiNewsObject *newsObj = [QQApiNewsObject objectWithURL:[NSURL URLWithString:link] title:title description:nil previewImageData:imageData];
[newsObj setCflag:kQQAPICtrlFlagQQShare];
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
QQApiSendResultCode sent = [QQApiInterface sendReq:req];
// QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
}
});
}
/// 文件 分享到微信
- (void)shareWeChatLink {
NSString *link = _url?:@"";
NSString *title = _fileName?:@"";
NSData *fileData = [NSData dataWithContentsOfURL:[NSURL URLWithString:link]];
dispatch_async(dispatch_get_main_queue(), ^{
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
WXMediaMessage *message = [WXMediaMessage message];
// 多媒体数据对象,可以为WXImageObject、WXMusicObject、WXVideoObject、WXWebpageObject、 WXAppExtendObject、WXFileObject、WXTextObject等
WXFileObject *ext = [WXFileObject object];
NSString *hz = [link componentsSeparatedByString:@"."].lastObject;
ext.fileExtension = hz?:@"";
ext.fileData = fileData;
// 多媒体数据对象
message.mediaObject = ext;
// 分享的链接介绍文本
// message.description = @"";
// 分享的链接标题
message.title = title;
// 给分享链接设置小图标
// [message setThumbImage:[UIImage imageNamed:@""]];
// 标记不是分享文本
req.bText = NO;
// 设置message对象
req.message = message;
// 分享目标场景
// 发送到聊天界面 WXSceneSession;
// 发送到朋友圈 WXSceneTimeline;
// 发送到微信收藏 WXSceneFavorite;
req.scene = WXSceneSession;
// 发送微信分享
BOOL isInstalled = [WXApi sendReq:req];
if (isInstalled == NO) {
// 调用微信分享识别 如:没有安装微信
}
});
}
[效果]
配置完成后,在备忘录输入链接,长按后会提示”在‘APP‘中打开“。用Safari打开网址时,顶部也会提示在”APP“中打开。
[TO]
微信和QQ的 Universal Link 配置
https://www.jianshu.com/p/abbdd9285bf6
微信开放文档
https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html
iOS中如何储存和分享文件给微信和QQ好友
https://www.jianshu.com/p/4f5f36658996
iOS-QQ分享功能实现
https://www.jianshu.com/p/581edba36b5b
iOS开发-微信分享
https://www.jianshu.com/p/d0d7c94bfd68
iOS - 开发针对iOS13QQ分享功能,弹框提示设备未授权 (错误码:25105)
https://blog.csdn.net/zhonggaorong/article/details/105094627
iOS Universal Links教程
https://www.jianshu.com/p/f1a1e1833eec
Universal Links 实现细节
https://www.jianshu.com/p/a42e3cdf550b