美文网首页程序员
我的APP不可能这么胖之微信好友分享

我的APP不可能这么胖之微信好友分享

作者: 萌恬丶 | 来源:发表于2017-07-18 13:52 被阅读105次

简介

这一系列讲述的是免SDK实现分享、登录、支付等业务。

将会使用ShareSDK Demo进行部分试验。

一、拦截分享参数

1、打开ShareSDK Demo,找到AppDelegate.m 添加如下代码

//头文件不要忘
#import <objc/runtime.h>

//对UIApplication的openURL:方法进行hook
-(void)swizzleOpenUrl{
    SEL openUrlSEL=@selector(openURL:);
    BOOL (*openUrlIMP)(id,SEL,id) =(BOOL(*)(id,SEL,id))[UIApplication instanceMethodForSelector:openUrlSEL];
    static int count=0;
    BOOL (^myOpenURL)(id SELF,NSURL * url)=^(id SELF,NSURL *url){
        
        //打印出分享的URL
        NSLog(@"\n----------open url: %d----------\n%@\n%@\n",count++,url,@"\n"/*[NSThread callStackSymbols]*/);
        
        //获取系统剪切板
        UIPasteboard * pasteboard = [UIPasteboard generalPasteboard];
        //打印获取微信在剪切板的key 得知key为 content
        NSLog(@"%@",pasteboard.pasteboardTypes);
        
        //获取微信在剪切板参数 微信所有内容都放在剪切板里,这与QQ是不同的
        NSData * wechatInfoData = [pasteboard valueForPasteboardType:@"content"];
        //微信是使用NSPropertyListSerialization做序列化的,这与QQ是不同的
        NSDictionary * wechatInfo = [NSPropertyListSerialization propertyListWithData:wechatInfoData options:0 format:NULL error:nil];
        NSLog(@"%@",wechatInfo);
        
        return (BOOL)openUrlIMP(SELF,openUrlSEL,url);
    };
    class_replaceMethod([UIApplication class], openUrlSEL, imp_implementationWithBlock(myOpenURL), NULL);
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    //只要添加这句
    [self swizzleOpenUrl];
}

2、查看控制台打印的URL

//weixin 微信 url scheme
//app 固定写法
//wx4868b35061f87885 app id
//sendreq 固定写法
weixin://app/wx4868b35061f87885/sendreq/?

3、参数解释

以下为微信好友分享参数,需要放到剪切板里

//外壳一个字典
{
    //微信app id
    wx4868b35061f87885 =     {
        
        //文字分享为1020 其余都是1010
        command = 1020; 
        //固定写法
        result = 1; 
        //固定写法
        returnFromApp = 0; 
        //0 微信好友 1微信朋友圈
        scene = 0; 
        //sdk版本号
        sdkver = "1.7.7"; 
        //文字分享时为分享内容
        //链接、网络音频、网络视频、应用消息、表情、文件时为标题
        title = "Share SDK"; 
        //图片、链接、音频、视频、应用消息、表情、文件时为分享内容
        description = "Share SDK";
        //图片分享时为分享图片的NSData数据(微信好友只能一张)
        //应用分享时为未知
        //表情分享时为分享表情的NSData数据(微信好友只能一张)
        //文件分享时为分享文件的NSData数据
        fileData = NSData数据
        //图片分享为 2
        //链接分享为 5
        //网络音频分享为 3
        //网络视频分享为 4
        //应用消息分享为 7
        //表情分享为 8
        //文件分享为 6
        //小程序分享为 36
        objectType = 2;
        //缩略图(小于32kb)
        //图片、链接、音频、视频、应用消息、表情、文件、小程序使用
        thumbData = NSData数据
        //链接时为网页地址
        //网络音频时为网络音频地址
        //网络视频时为网络音频地址
        //应用消息时为网页地址
        mediaUrl = "https://www.mob.com";
        //扩展信息 应用消息分享时用到
        extInfo = "<xml>extend info</xml>";
        //小程序用到 跳转到页面路径
        appBrandPath = "/page/API/pages/share/share";
        //小程序用到 小程序的名称
        appBrandUserName = "gh_d43f693ca31f";
        //文件分享时用到 为文件类型
        fileExt = mp4
    };
}

二、构造分享参数

代码仅供参考,部分代码做了封装,需要到demo里的TWeChatPlatform类查看。

//微信好友分享
+ (NSString *)shareToWechatSessionParameters:(NSMutableDictionary *)parameters appId:(NSString *)appId onStateChanged:(TStateChangedHandler)stateChangedHandler {
    
    [TWeChatPlatform shareInstance].appid = appId;
    
    if (stateChangedHandler) {
        [TWeChatPlatform shareInstance].stateChangedHandler = stateChangedHandler;
    }
    
    if ([TWeChatPlatform isWeChatInstalled]) {
        TContentType TPlatformType = [[parameters typeForParams] integerValue];
        NSDictionary * wechatDic = nil;
        if (TPlatformType == TContentTypeText) {
            //文本
            wechatDic =  @{@"command" : @"1020",
                           @"result" : @"1",
                           @"returnFromApp" : @"0",
                           @"scene" : @"0",
                           @"sdkver" : @"1.7.7",
                           @"title" : [parameters textForParams]};
        }
        else if (TPlatformType == TContentTypeImage && [parameters emoticonDataForParams] == nil) {
            //图片
            NSAssert([parameters imagesForParams], @"图片分享,图片不能为空");
            NSArray * imageArray = [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:NO];
            NSArray * thumbData = [parameters thumbImageForParams] == nil ? [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:YES] : [NSMutableArray arrayWithImages:[parameters thumbImageForParams] isCompress:YES];
            
            wechatDic =  @{@"command" : @"1010",
                           @"description" : [parameters textForParams],
                           @"fileData" : imageArray[0],
                           @"objectType" : @"2",
                           @"result" : @"1",
                           @"returnFromApp" : @"0",
                           @"scene" : @"0",
                           @"sdkver" : @"1.7.7",
                           @"thumbData" : thumbData[0]
                           };
        }
        else if (TPlatformType == TContentTypeWebPage) {
            
            //链接
            NSArray * thumbData;
            if ([parameters thumbImageForParams] == nil && [parameters imagesForParams] != nil) {
                //缩略图为空 大图不为空
                thumbData = [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:YES];
            }
            else  {
                //缩略图 或者 没缩略图都走这个
                thumbData = [NSMutableArray arrayWithImages:[parameters thumbImageForParams] isCompress:YES];
            }
            
            wechatDic =  @{@"command" : @"1010",
                           @"description" : [parameters textForParams],
                           @"thumbData" : thumbData[0],
                           @"mediaUrl" : [parameters urlForParams].absoluteString,
                           @"objectType" : @"5",
                           @"result" : @"1",
                           @"returnFromApp" : @"0",
                           @"scene" : @"0",
                           @"sdkver" : @"1.7.7",
                           @"title" : [parameters titleForParams]
                           };
        }
        else if (TPlatformType == TContentTypeAudio) {
            
            //音频
            NSArray * thumbData;
            if ([parameters thumbImageForParams] == nil && [parameters imagesForParams] != nil) {
                //缩略图为空 大图不为空
                thumbData = [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:YES];
            }
            else  {
                //缩略图 或者 没缩略图都走这个
                thumbData = [NSMutableArray arrayWithImages:[parameters thumbImageForParams] isCompress:YES];
            }
            
            wechatDic =  @{@"command" : @"1010",
                           @"description" : [parameters textForParams],
                           @"thumbData" : thumbData[0],
                           @"mediaUrl" : [parameters urlForParams].absoluteString,
                           @"objectType" : @"3",
                           @"result" : @"1",
                           @"returnFromApp" : @"0",
                           @"scene" : @"0",
                           @"sdkver" : @"1.7.7",
                           @"title" : [parameters titleForParams]
                           };
            
        }
        else if (TPlatformType == TContentTypeVideo) {
            
            //视频
            NSArray * thumbData;
            if ([parameters thumbImageForParams] == nil && [parameters imagesForParams] != nil) {
                //缩略图为空 大图不为空
                thumbData = [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:YES];
            }
            else  {
                //缩略图 或者 没缩略图都走这个
                thumbData = [NSMutableArray arrayWithImages:[parameters thumbImageForParams] isCompress:YES];
            }
            
            wechatDic =  @{@"command" : @"1010",
                           @"description" : [parameters textForParams],
                           @"thumbData" : thumbData[0],
                           @"mediaUrl" : [parameters urlForParams].absoluteString,
                           @"objectType" : @"4",
                           @"result" : @"1",
                           @"returnFromApp" : @"0",
                           @"scene" : @"0",
                           @"sdkver" : @"1.7.7",
                           @"title" : [parameters titleForParams]
                           };
            
        }
        else if (TPlatformType == TContentTypeApp) {
            
            //应用消息
            NSArray * thumbData;
            if ([parameters thumbImageForParams] == nil && [parameters imagesForParams] != nil) {
                //缩略图为空 大图不为空
                thumbData = [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:YES];
            }
            else  {
                //缩略图 或者 没缩略图都走这个
                thumbData = [NSMutableArray arrayWithImages:[parameters thumbImageForParams] isCompress:YES];
            }
            wechatDic =  @{@"command" : @"1010",
                           @"description" : [parameters textForParams],
                           @"thumbData" : thumbData[0],
                           @"mediaUrl" : [parameters urlForParams].absoluteString,
                           @"objectType" : @"7",
                           @"result" : @"1",
                           @"returnFromApp" : @"0",
                           @"scene" : @"0",
                           @"sdkver" : @"1.7.7",
                           @"title" : [parameters titleForParams],
                           @"extInfo" : [parameters extInfoForParams],
                           @"fileData" : [parameters fileDataForParams]
                           };
            
        }
        else if (TPlatformType == TContentTypeImage && [parameters emoticonDataForParams]) {
            //表情图片
            NSAssert([parameters emoticonDataForParams], @"emoticonData 不能为空,传表情图片");
            NSData * imageData = [NSData dataWithContentsOfFile:[parameters emoticonDataForParams]];
            NSArray * thumbData =  [NSMutableArray arrayWithImages:[parameters thumbImageForParams] isCompress:YES];
            
            wechatDic =  @{@"command" : @"1010",
                           @"description" : [parameters textForParams],
                           @"fileData" : imageData,
                           @"objectType" : @"8",
                           @"result" : @"1",
                           @"returnFromApp" : @"0",
                           @"scene" : @"0",
                           @"sdkver" : @"1.7.7",
                           @"thumbData" : thumbData[0]
                           };
        }
        else if (TPlatformType == TContentTypeFile) {
            //文件 仅微信可用
            NSArray * thumbData;
            if ([parameters thumbImageForParams] == nil && [parameters imagesForParams] != nil) {
                //缩略图为空 大图不为空
                thumbData = [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:YES];
            }
            else  {
                //缩略图 或者 没缩略图都走这个
                thumbData = [NSMutableArray arrayWithImages:[parameters thumbImageForParams] isCompress:YES];
            }
            
            NSAssert([parameters sourceFileData], @"文件路径不能为空");
            NSString * sourceFile = [parameters sourceFileData];
            NSData * sourceFileData = [NSData dataWithContentsOfFile:sourceFile];
            
            wechatDic =  @{@"command" : @"1010",
                           @"fileData" : sourceFileData,
                           @"objectType" : @"6",
                           @"result" : @"1",
                           @"returnFromApp" : @"0",
                           @"scene" : @"0",
                           @"sdkver" : @"1.7.7",
                           @"thumbData" : thumbData[0],
                           @"fileExt" : [parameters sourceFileExtension],
                           @"title" : [parameters titleForParams],
                           @"description" : [parameters textForParams]
                           };
            
        }
        
        [UIPasteboard setPasteboard:@"content" value:@{appId : wechatDic} encoding:TPboardEncodingPropertyListSerialization];
        return [NSString stringWithFormat:@"weixin://app/%@/sendreq/?",appId];
    }
    else {
        
        if (stateChangedHandler) {
            NSError * err = [NSError errorWithDomain:@"TrochilusErrorDomain" code:-1002 userInfo:@{@"error_message":@"分享平台[微信]尚未安装客户端!无法进行分享!"}];
            stateChangedHandler(TResponseStateFail,nil,err);
        }
        
    }
    
    return nil;
}

三、发起请求

代码仅供参考,部分代码做了封装,需要到demo里的Trochilus类查看。

+ (void)share:(TPlatformType)platformType parameters:(NSMutableDictionary *)parameters onStateChanged:(TStateChangedHandler)stateChangedHandler {
    
    NSString * shareUrl = @"";
    switch (platformType) {
        case TPlatformSubTypeWechatSession: {
            //微信朋友
            shareUrl = [TWeChatPlatform shareToWechatSessionParameters:parameters
                                                                appId:[self platformForKey:weChat][@"appId"]
                                                       onStateChanged:^(TResponseState state, NSDictionary *userData, NSError *error) {
                                                           
                                                           if (stateChangedHandler) {
                                                               stateChangedHandler(state,userData,error);
                                                           }
                                                       }];
        }
            break;
        default:
            break;
    }
    
    [Trochilus sendToURL:shareUrl];
}

+ (void)sendToURL:(NSString *)url {
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
    });
    
}

四、微信客户端回调

代码仅供参考,部分代码做了封装,需要到demo里的TWeChatPlatform类查看。

微信的分享返回值也是放在剪切板里。

+ (BOOL)handleUrlWithWeChat:(NSURL *)url {
    
    if ([url.scheme hasPrefix:@"wx"]) {
        
       //获取剪切板内容
        UIPasteboard * pasteboard = [UIPasteboard generalPasteboard];
        NSLog(@"%@",pasteboard.pasteboardTypes);
        //微信分享
        //            {
        //                wx4868b35061f87885 =     {
        //                    command = 2020;
        //                    country = CN;
        //                    language = "zh_CN";
        //                    result = 0;
        //                    returnFromApp = 0;
        //                    sdkver = "1.5";
        //                };
        //            }
        //获取剪切板内容 content 是通过上面打印得知的
        NSData * wechatData = [pasteboard valueForPasteboardType:@"content"];
        
        //微信的NSData序列号方式为NSPropertyListSerialization
        NSDictionary * wechatInfo = [NSPropertyListSerialization propertyListWithData:wechatData options:0 format:NULL error:nil];
        NSLog(@"%@",wechatInfo);
        
        //获取微信返回值
        NSDictionary * wechatResponse = wechatInfo[[TWeChatPlatform shareInstance].appid];
        
        if ([wechatResponse[@"result"] integerValue] == 0) {
            //分享成功
            if ([TWeChatPlatform shareInstance].stateChangedHandler) {
                [TWeChatPlatform shareInstance].stateChangedHandler(TResponseStateSuccess,nil,nil);
            }
        }
        else if ([wechatResponse[@"result"] integerValue] == -2) {
            //用户点击取消并返回
            if ([TWeChatPlatform shareInstance].stateChangedHandler) {
                [TWeChatPlatform shareInstance].stateChangedHandler(TResponseStateCancel,nil,nil);
            }
        }
        else {
            //分享失败
            NSError * err = [NSError errorWithDomain:@"WechatDomain" code:[wechatResponse[@"result"] integerValue] userInfo:wechatResponse];
            if ([TWeChatPlatform shareInstance].stateChangedHandler) {
                [TWeChatPlatform shareInstance].stateChangedHandler(TResponseStateFail,nil,err);
            }
        }
            
        return YES;
    }
    return NO;
}

五、参考资料

https://github.com/100apps/openshare

六、Demo

https://github.com/quanweiwang/Trochilus

目录

分享篇
1、我的APP不可能这么胖之QQ好友分享
2、我的APP不可能这么胖之QQ空间分享
3、我的APP不可能这么胖之微信好友分享
4、我的APP不可能这么胖之微信朋友圈分享
5、我的APP不可能这么胖之新浪微博分享
登录篇
6、我的APP不可能这么胖之QQ登录
7、我的APP不可能这么胖之微信登录
8、我的APP不可能这么胖之新浪微博登录
支付篇
9、我的APP不可能这么胖之微信支付
10、我的APP不可能这么胖之支付宝支付

相关文章

网友评论

    本文标题:我的APP不可能这么胖之微信好友分享

    本文链接:https://www.haomeiwen.com/subject/hvfhkxtx.html