我的APP不可能这么胖之新浪微博分享

简介

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

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

一、拦截分享参数

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

//头文件不要忘
#import 

//对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];
        //新浪微博的参数也是放在剪切板里但是与微信又不一样
        //新浪微博分享参数
        //这里演示文字分享,不同的分享类型参数也不同
        /*
         (
            {
                transferObject = <62706c69 73743030 d4010203 04050634 35582476 65727369 6f6e5824 6f626a65 63747359 24617263 68697665 72542474 6f701200 0186a0ad 07081516 1718191d 252d2e2f 3055246e 756c6cd3 090a0b0c 1014574e 532e6b65 79735a4e 532e6f62 6a656374 73562463 6c617373 a30d0e0f 80028003 8004a311 12138005 80068008 800c575f 5f636c61 73735972 65717565 73744944 576d6573 73616765 5f101b57 4253656e 644d6573 73616765 546f5765 69626f52 65717565 7374d20b 1a1b1c59 4e532e73 7472696e 6780075f 10243135 30303132 44302d37 3943412d 34443644 2d394338 382d3843 35423334 42373941 4146d21e 1f20215a 24636c61 73736e61 6d655824 636c6173 7365735f 100f4e53 4d757461 626c6553 7472696e 67a32223 245f100f 4e534d75 7461626c 65537472 696e6758 4e535374 72696e67 584e534f 626a6563 74d3090a 0b262914 a20d2880 028009a2 2a2b800a 800b800c 54746578 745f100f 57424d65 73736167 654f626a 65637459 53686172 65205344 4bd21e1f 31325f10 134e534d 75746162 6c654469 6374696f 6e617279 a3313324 5c4e5344 69637469 6f6e6172 795f100f 4e534b65 79656441 72636869 766572d1 36375472 6f6f7480 01000800 11001a00 23002d00 32003700 45004b00 52005a00 65006c00 70007200 74007600 7a007c00 7e008000 82008a00 94009c00 ba00bf00 c900cb00 f200f701 02010b01 1d012101 33013c01 45014c01 4f015101 53015601 58015a01 5c016101 73017d01 82019801 9c01a901 bb01be01 c3000000 00000002 01000000 00000000 38000000 00000000 00000000 00000001 c5>;
            },
            {
                userInfo = <62706c69 73743030 d4010203 0405061a 1b582476 65727369 6f6e5824 6f626a65 63747359 24617263 68697665 72542474 6f701200 0186a0a5 07081112 1355246e 756c6cd3 090a0b0c 0e10574e 532e6b65 79735a4e 532e6f62 6a656374 73562463 6c617373 a10d8002 a10f8003 80045973 74617274 54696d65 5f101732 3031372d 30372d31 30203135 3a33353a 30373a35 3432d214 1516175a 24636c61 73736e61 6d655824 636c6173 7365735f 10134e53 4d757461 626c6544 69637469 6f6e6172 79a31618 195c4e53 44696374 696f6e61 7279584e 534f626a 6563745f 100f4e53 4b657965 64417263 68697665 72d11c1d 54726f6f 74800108 111a232d 32373d43 4a525d64 66686a6c 6e789297 a2abc1c5 d2dbedf0 f5000000 00000001 01000000 00000000 1e000000 00000000 00000000 00000000 f7>;
            },
            {
                app = <62706c69 73743030 d4010203 04050622 23582476 65727369 6f6e5824 6f626a65 63747359 24617263 68697665 72542474 6f701200 0186a0a9 07081516 1718191a 1b55246e 756c6cd3 090a0b0c 1014574e 532e6b65 79735a4e 532e6f62 6a656374 73562463 6c617373 a30d0e0f 80028003 8004a311 12138005 80068007 80085361 69645862 756e646c 65494456 6170704b 65795f10 32303141 6f444c77 35652d47 45677134 6a6a7855 576d7559 56324361 6b376143 43714d5a 4a7a5756 61354f43 515f4d58 50632e5f 1018636f 6d2e7761 6e677175 616e7765 692e5368 61726553 444b5a33 31383339 30333336 37d21c1d 1e1f5a24 636c6173 736e616d 65582463 6c617373 65735f10 134e534d 75746162 6c654469 6374696f 6e617279 a31e2021 5c4e5344 69637469 6f6e6172 79584e53 4f626a65 63745f10 0f4e534b 65796564 41726368 69766572 d1242554 726f6f74 80010008 0011001a 0023002d 00320037 00410047 004e0056 00610068 006c006e 00700072 00760078 007a007c 007e0082 008b0092 00c700e2 00ed00f2 00fd0106 011c0120 012d0136 0148014b 01500000 00000000 02010000 00000000 00260000 00000000 00000000 00000000 0152>;
            },
            {
                sdkVersion = <30303332 30333030 30>;
            }
         )

         */
        NSArray * sinaWeiBoInfo = pasteboard.items;
        NSLog(@"%@",sinaWeiBoInfo);
        
        //解析transferObject结构
        NSDictionary * transferObjectDic = sinaWeiBoInfo[0];
        NSData * transferObjectData = transferObjectDic[@"transferObject"];
        /*
         Printing description of transferObject:
         {
            "__class" = WBSendMessageToWeiboRequest;
            message =     {
                "__class" = WBMessageObject;
                text = "Share SDK";
            };
            requestID = "1B12FB5E-0F80-45A4-A86A-D1EA1A75ABB7"; //UUID
         }
         */
        NSDictionary * transferObject = [NSKeyedUnarchiver unarchiveObjectWithData:transferObjectData];
        NSLog(@"%@",transferObject);
        
        /*
         {
            startTime = "2017-07-10 15:47:27:182";
         }
         */
        NSDictionary * userInfoDic = sinaWeiBoInfo[1];
        NSData * userInfoData = userInfoDic[@"userInfo"];
        NSDictionary * userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:userInfoData];
        NSLog(@"%@",userInfo);
        
        /*
         {
            aid = "01AoDLw5e-GEgq4jjxUWmuYV2Cak7aCCqMZJzWVa5OCQ_MXPc.";
            appKey = 3183903367;
            bundleID = "com.wangquanwei.ShareSDK";
         }
         */
        NSDictionary * appDic = sinaWeiBoInfo[2];
        NSData * appData = appDic[@"app"];
        NSDictionary * app = [NSKeyedUnarchiver unarchiveObjectWithData:appData];
        NSLog(@"%@",app);
        
        //003203000
        NSDictionary * sdkVersionDic = sinaWeiBoInfo[3];
        NSData * sdkVersionData = sdkVersionDic[@"sdkVersion"];
        NSString * sdkVersion = [[NSString alloc] initWithData:sdkVersionData encoding:NSUTF8StringEncoding];
        NSLog(@"%@",sdkVersion);
        
        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

//weibosdk 微博的url scheme
//request 固定写法
//id UUID
//sdkversion sdk版本号
//luicode 不知道
//lfid bundle id
weibosdk://request?id=183DFA52-1E35-4CDD-A7A9-5A093CE2B0AF&sdkversion=003203000&luicode=10000360&lfid=com.wangquanwei.ShareSDK

3、参数解释

以下为新浪微博分享参数,需要放到剪切板里

//外壳一个数组 
//transferObject、userInfo、app、sdkVersion的结果都需要NSKeyedArchiver序列化
//这里为了方便讲解所以给出原始值

//文字分享
(
        {
            transferObject = {
                                "__class" = WBSendMessageToWeiboRequest; //分享固定写法
                                message =     {
                                    "__class" = WBMessageObject;    //分享类型
                                    text = "Share SDK";             //分享内容
                                };
                                requestID = "1B12FB5E-0F80-45A4-A86A-D1EA1A75ABB7"; //UUID
                            };
        },
        {
            userInfo = {
                            startTime = "2017-07-10 15:47:27:182"; //时间 精确到毫秒
                        };
        },
        {
            app = {
                    aid = "01AoDLw5e-GEgq4jjxUWmuYV2Cak7aCCqMZJzWVa5OCQ_MXPc."; //新浪微博sdk的apple 广告id 
                    appKey = 3183903367; //新浪微博appkey
                    bundleID = "com.wangquanwei.ShareSDK"; //bundle id
                };
        },
        {
            sdkVersion = "003203000"; sdk版本号
        }
)

//文字+图片分享
(
        {
            transferObject = {
                                "__class" = WBSendMessageToWeiboRequest; //分享固定写法
                                message =     {
                                    "__class" = WBMessageObject;    //分享类型
                                    text = "Share SDK";             //分享内容
                                    imageObject =   {
                                                        imageData = //UIImage的NSData对象 只支持1张图片
                                                    }
                                };
                                requestID = "1B12FB5E-0F80-45A4-A86A-D1EA1A75ABB7"; //UUID
                            };
        },
        {
            userInfo = {
                            startTime = "2017-07-10 15:47:27:182"; //时间 精确到毫秒
                        };
        },
        {
            app = {
                    aid = "01AoDLw5e-GEgq4jjxUWmuYV2Cak7aCCqMZJzWVa5OCQ_MXPc."; //新浪微博sdk的apple 广告id 
                    appKey = 3183903367; //新浪微博appkey
                    bundleID = "com.wangquanwei.ShareSDK"; //bundle id
                };
        },
        {
            sdkVersion = "003203000"; sdk版本号
        }
)

//链接分享
(
        {
            transferObject = {
                                "__class" = WBSendMessageToWeiboRequest; //分享固定写法
                                message =     {
                                                    "__class" = WBMessageObject;
                                                    mediaObject =   {
                                                                        "__class" = WBWebpageObject; //web分享
                                                                        description = "Share SDK Link Desc"; //分享内容
                                                                        objectID = 1499674138987; //13位时间戳
                                                                        thumbnailData = //UIImage的NSData对象 只支持1张图片 不要大于32k;
                                                                        title = MOB; //链接标题
                                                                        webpageUrl = "http://www.mob.com"; //链接地址
                                                                    };
                                                    text = "Share SDK Link Desc"; //分享内容
                                                };
                                
                                requestID = "1B12FB5E-0F80-45A4-A86A-D1EA1A75ABB7"; //UUID
                            };
        },
        {
            userInfo = {
                            startTime = "2017-07-10 15:47:27:182"; //时间 精确到毫秒
                        };
        },
        {
            app = {
                    aid = "01AoDLw5e-GEgq4jjxUWmuYV2Cak7aCCqMZJzWVa5OCQ_MXPc."; //新浪微博sdk的apple 广告id 
                    appKey = 3183903367; //新浪微博appkey
                    bundleID = "com.wangquanwei.ShareSDK"; //bundle id
                };
        },
        {
            sdkVersion = "003203000"; sdk版本号
        }
)

二、构造分享参数

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

+ (NSString *)shareToSinaWeiBoParameters:(NSMutableDictionary *)parameters appId:(NSString *)appId redirectURI:(NSString *)redirectURI onStateChanged:(TStateChangedHandler)stateChangedHandler {
    
    if (stateChangedHandler) {
        [TSinaWeiBoPlatform shareInstance].stateChangedHandler = stateChangedHandler;
    }
    
    if ([TSinaWeiBoPlatform isSinaWeiBoInstalled]) {
        NSString * uuid = [[NSUUID UUID] UUIDString];
        
        NSDictionary * message = nil;
        TContentType type = [[parameters typeForParams] integerValue];
        
        if (type == TContentTypeText) {
            //文字分享
            message = @{@"__class" : @"WBMessageObject",
                        @"text" : [parameters textForParams]};
        }
        else if (type == TContentTypeImage) {
            //图片 分享 貌似只能分享一张图片
            NSAssert([parameters imagesForParams], @"图片分享,图片不能为空");
            NSArray * images = [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:NO];
            NSDictionary * imageData = @{@"imageData" : images[0]};
            message = @{@"__class" : @"WBMessageObject",
                        @"text" : [parameters textForParams],
                        @"imageObject" : imageData};
        }
        else if (type == TContentTypeWebPage) {
            //链接分享
            
            //时间戳
            NSTimeInterval timeInterval = [[NSDate date] timeIntervalSince1970] * 1000;
            NSString * timeIntervalStr = [NSString stringWithFormat:@"%ld",(long)timeInterval];
            //缩略图
            NSArray * thumbnail = [NSMutableArray arrayWithImages:[parameters imagesForParams] isCompress:YES];
            
            
            NSDictionary * mediaObject = @{@"__class" : @"WBWebpageObject",
                                           @"description" : [parameters textForParams],
                                           @"objectID" : timeIntervalStr,
                                           @"thumbnailData" : thumbnail[0],
                                           @"title" : [parameters titleForParams],
                                           @"webpageUrl" : [parameters urlForParams].absoluteString
                                           };
            message = @{@"__class" : @"WBMessageObject",
                        @"text" : [parameters textForParams],
                        @"mediaObject" : mediaObject};
        }
        
        NSDictionary * transferObject = @{@"__class" : @"WBSendMessageToWeiboRequest",
                                          @"requestID" : uuid,
                                          @"message" : message
                                          };
        NSData * transferObjectData = [NSKeyedArchiver archivedDataWithRootObject:transferObject];
        NSDictionary * transferObjectDic = @{@"transferObject" : transferObjectData};
        
        //获取当前时间 精确到毫秒
        NSString * currentDate = @"";
        NSDateFormatter * formatter = [[NSDateFormatter alloc ] init];
        [formatter setDateFormat:@"YYYY-MM-dd hh:mm:ss:SSS"];
        currentDate = [formatter stringFromDate:[NSDate date]];
        
        NSDictionary * userInfo = @{@"startTime" : currentDate};
        NSData * userInfoData = [NSKeyedArchiver archivedDataWithRootObject:userInfo];
        NSDictionary * userInfoDic = @{@"userInfo" : userInfoData};
        
        //这里还有个参数aid 不知道干嘛的
        //aid = "01AoDLw5e-GEgq4jjxUWmuYV2Cak7aCCqMZJzWVa5OCQ_MXPc."
        NSDictionary * app = @{@"appKey" : appId,
                               @"bundleID" : kCFBundleIdentifier,
                               @"aid" : @"01AoDLw5e-GEgq4jjxUWmuYV2Cak7aCCqMZJzWVa5OCQ_MXPc."};
        NSData * appData = [NSKeyedArchiver archivedDataWithRootObject:app];
        NSDictionary * appDic = @{@"app" : appData};
        
        NSData * sdkVersionData = [@"003203000" dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary * sdkVersion = @{@"sdkVersion" : sdkVersionData};
        
        NSArray * sinaWeiBoArray = @[transferObjectDic,userInfoDic,appDic,sdkVersion];
        
        UIPasteboard * pasteboard = [UIPasteboard generalPasteboard];
        [pasteboard setItems:sinaWeiBoArray];
        
        return [NSMutableString stringWithFormat:@"weibosdk://request?id=%@&sdkversion=003203000&luicode=10000360&lfid=%@",uuid,kCFBundleIdentifier];
    }
    else {
        
        if (stateChangedHandler) {
            NSError * err = [NSError errorWithDomain:@"TrochilusErrorDomain" code:-1003 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 TPlatformTypeSinaWeibo: {
            
            //分享
            shareUrl = [TSinaWeiBoPlatform shareToSinaWeiBoParameters:parameters
                                                               appId:[self platformForKey:sinaWeiBo][@"appKey"]
                                                         redirectURI:[self platformForKey:sinaWeiBo][@"redirectUri"]
                                                      onStateChanged:^(TResponseState state, NSDictionary *userData, NSError *error) {
                                                          
                                                          if (stateChangedHandler) {
                                                              stateChangedHandler(state,userData,error);
                                                          }
                                                      }];
            
        }
        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里的WeChatPlatform类查看。

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

+ (BOOL)handleUrlWithSinaWeiBo:(NSURL *)url {
    
    UIPasteboard * pasteboard = [UIPasteboard generalPasteboard];
    NSArray * sinaweiboArray = pasteboard.items;
    
    //这里的transferObjectDic是授权后微博返回的,数据跟我们发送的已经不一样了
    NSDictionary * transferObjectDic = sinaweiboArray[0];
    NSData * transferObjectData = transferObjectDic[@"transferObject"];
    NSDictionary * transferObject = [NSKeyedUnarchiver unarchiveObjectWithData:transferObjectData];
    
    if ([transferObject[@"__class"] isEqualToString:@"WBSendMessageToWeiboResponse"]) {
        //分享
        if ([transferObject[@"statusCode"] integerValue] == 0) {
            //分享成功
            if ([TSinaWeiBoPlatform shareInstance].stateChangedHandler) {
                [TSinaWeiBoPlatform shareInstance].stateChangedHandler(TResponseStateSuccess, nil, nil);
            }
            
        }
        else if ([transferObject[@"statusCode"] integerValue] == -1) {
            //用户取消发送
            if ([TSinaWeiBoPlatform shareInstance].stateChangedHandler) {
                [TSinaWeiBoPlatform shareInstance].stateChangedHandler(TResponseStateCancel, nil, nil);
            }
        }
        else if ([transferObject[@"statusCode"] integerValue] == -2 || [transferObject[@"statusCode"] integerValue] == -8) {
            //发送失败
            //还有种状态-8 分享失败 详情见response UserInfo 等遇到在补充
            if ([TSinaWeiBoPlatform shareInstance].stateChangedHandler) {
                NSError *err=[NSError errorWithDomain:@"WeiBoDomain" code:[transferObject[@"statusCode"] intValue] userInfo:transferObject];
                [TSinaWeiBoPlatform shareInstance].stateChangedHandler(TResponseStateFail, nil, err);
            }
        }
        return YES;
    }
    
    return NO;
}


五、参考资料

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

https://sanwen8.cn/p/1aagMSi.html

六、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不可能这么胖之新浪微博分享)