iOS 微博登录、分享的实现

本内容将记录 微博 的登录和分享功能,当然微博也有支付功能,但是微博的支付功能使用的还是比较少的,一般使用马大大的 支付宝或者小马的 微信作为第三方支付功能。

微博开放平台链接地址: https://open.weibo.com/

微博iOS-SDK文档 (具体使用可看微博SDK开发文档): https://github.com/sinaweibosdk/weibo_ios_sdk

移动端接入+SDK功能特性: http://open.weibo.com/wiki/%E7%A7%BB%E5%8A%A8%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%8E%A5%E5%85%A5

最新版本的微博登录需要实现以下步骤:

  1. 在新浪微博公共开放平台并注册应用(https://open.weibo.com/)
  2. 需要在 "我的应用"=> "应用信息"=>"高级信息"中填写应用的默认授权回调页 https://api.weibo.com/oauth2/default.html
  3. 已选择应用为 iphone 平台,并正确填写 Bundle idapple id (要与Xcode 工程中的bundle相对应)

在上面的各个步骤中是需要完成对新浪微博的开发者的注册和应用的注册并提交审核;最后我们需要达到的效果是拿到我们需要的应用对应的 AppKeyAppSecert这两个用于我们接下来的整个应用开发。

集成 weibosdk 并添加Xcode项目的各项配置-->

1. 设置工程回调的 URL Scheme

Targets->Info->URL Types中 点击 +新增用于微博的URL Scheme回调

Identifier可随便填写,URL Schemes-> wb+AppKey(如:we222222)

iOS-sinaweibo-URLSchemes.png

2. 添加 weibo SDK文件到工程

根据教程我们可以使用直接添加weibo SDK或者使用cocoapods吧weiboSDK添加入项目中去。我一般不论使用微博/微信/QQ登录或者支付等导入功能时一般选择直接拖入,一来这样其实比pod入工程更加方便管理,而且不会随着官方的更新而更新,避免导致未知的错误。

微博SDK下载地址为--github: https://github.com/sinaweibosdk/weibo_ios_sdk

一般 拖入工程的SDK包括如下内容:


iOS-sinaweibo-sdk.png

3. 在SDK拖入工程后,给工程中添加必要的配置 Frameworks and LibrariesBuild Setting

为了避免静态库中类加载 不全造成程序崩溃,在 Target->Buid Settings->Linking 下 Other Linker Flags 项添加 -ObjC参数。

在⼯程中修改Other Linker Flags后,需要修改编译步骤的链接库设置,避免链接阶
段由于库的设置错误导致程序崩溃。添加必要的 FrameWorks/Libraries,
添加步骤为: Target->Build Phases->Link Binary with Libraries/Target->General->Link Frameworks and Libraries

总共需要添加这些库:

Photos.framework
QuartzCore.framework
ImageIO.framework、
SystemConfiguration.framework、
Security.framework、
CoreTelephony.framework、
CoreText.framework、
UIKit.framework、
Foundation.framework、
CoreGraphics.framework 、
libz.dylib、
libsqlite3.dylib。
iOS-sinaweiboSDK-FrameworkScreen.png

4. 在 Info.plist 文件中 添加白名单

LSApplicationQueriesSchemes -->

iOS-sinaweiboSDK-Queries.png

<font color=#8E236B> 在所有配置完成后具体添加实现微博登录的代码: </font>

1. 在 AppDelegate.m 中实现

    1. import `#import "WeiboSDK.h"` 

    2. `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`
加入   
    [WeiboSDK enableDebugMode:YES];
    [WeiboSDK registerApp:kSinaweiboAppKey]; // 注册应用时申请的AppKey
    
   3.  /*  微博登录使用 -- 必须使用下面方法,否则会报错 */
加入代码:  // 此处的 `WeiboSDKVCDelegate` 是自定义的 WebiboSDk delegate 类  
// 此处的 [WeiboSDKVCDelegate class] 作为代理需要使用类方法作为类的代理响应
// 若为 [[WeiboSDKVCDelegate alloc]init] 则可实现代理的对象方法,否则会出现 `unrecognizer selector`
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    if ([WeiboSDK handleOpenURL:url delegate:[[WeiboSDKVCDelegate alloc]init]]) {
        return YES;
    }
    return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    // [[WeiboSDKVCDelegate alloc]init]
    // (id<WeiboSDKDelegate>)[WeiboSDKVCDelegate class]
    if ([WeiboSDK handleOpenURL:url delegate:[[WeiboSDKVCDelegate alloc]init]]) {
        return YES;
    }
    return YES;
}
   

2. 实现微博的SDK delegate响应

`WeiboSDKVCDelegate.m`

/**
 收到一个来自微博客户端程序的请求
 
 收到微博的请求后,第三方应用应该按照请求类型进行处理,处理完后必须通过 [WeiboSDK sendResponse:] 将结果回传给微博
 @param request 具体的请求对象
 */
- (void)didReceiveWeiboRequest:(WBBaseRequest *)request{ //向微博发送请求
    NSLog(@" %@",request.class);
}

#pragma mark - didReceiveWeiboResponse
/**
 微博分享  与 微博登录,成功与否都会走这个方法。 用户根据自己的业务进行处理。
 收到一个来自微博客户端程序的响应
 
 收到微博的响应后,第三方应用可以通过响应类型、响应的数据和 WBBaseResponse.userInfo 中的数据完成自己的功能
 @param response 具体的响应对象
 */
- (void)didReceiveWeiboResponse:(WBBaseResponse *)response{
    NSLog(@"log--didReceiveWeiboResponse:%@",response);

        // 此代理方法不可使用 -- 由于AppDelegate中的调用对象和被回调控制器中的对象属于同一个类但不同属于同一对象造成
//        if ([_weiboDelegate respondsToSelector:@selector(weiboLoginByResponse:)]) {
//            [_weiboDelegate weiboLoginByResponse:response];
//        }
    
    // 分享时回调使用
    if ([response isKindOfClass:WBSendMessageToWeiboResponse.class])
    {
        [[NSNotificationCenter defaultCenter]postNotificationName:@"didReceiveWeiboWBSendMessageToWeiboResponse" object:response];
        
//        NSString *title = NSLocalizedString(@"发送结果", nil);
//        NSString *message = [NSString stringWithFormat:@"%@: %d\n%@: %@\n%@: %@", NSLocalizedString(@"响应状态", nil), (int)response.statusCode, NSLocalizedString(@"响应UserInfo数据", nil), response.userInfo, NSLocalizedString(@"原请求UserInfo数据", nil),response.requestUserInfo];
//        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
//                                                        message:message
//                                                       delegate:nil
//                                              cancelButtonTitle:NSLocalizedString(@"确定", nil)
//                                              otherButtonTitles:nil];
//        WBSendMessageToWeiboResponse* sendMessageToWeiboResponse = (WBSendMessageToWeiboResponse*)response;
//        NSString* accessToken = [sendMessageToWeiboResponse.authResponse accessToken];
//        if (accessToken)
//        {
//            self.wbtoken = accessToken;
//        }
//        NSString* userID = [sendMessageToWeiboResponse.authResponse userID];
//        if (userID) {
//            self.wbCurrentUserID = userID;
//        }
//        [alert show];
            
    } // 登录时回调使用
    else if ([response isKindOfClass:WBAuthorizeResponse.class])
    {
        
        // 发送登录成功或者失败或者某种情况的通知
        [[NSNotificationCenter defaultCenter]postNotificationName:@"didReceiveWeiboResponseInWBAuthorizeResponse" object:response];
        
        //        NSString *title = NSLocalizedString(@"认证结果", nil);
        //
        //        // request/response string
        //        NSString *message = [NSString stringWithFormat:@"%@: %d\nresponse.userId: %@\nresponse.accessToken: %@\n%@: %@\n%@: %@", NSLocalizedString(@"响应状态", nil), (int)response.statusCode,[(WBAuthorizeResponse *)response userID], [(WBAuthorizeResponse *)response accessToken],  NSLocalizedString(@"响应UserInfo数据", nil), response.userInfo, NSLocalizedString(@"原请求UserInfo数据", nil), response.requestUserInfo];
        // alert show
//        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
//                                                        message:message
//                                                       delegate:nil
//                                              cancelButtonTitle:NSLocalizedString(@"确定", nil)
//                                              otherButtonTitles:nil];
//
//        [alert show];
    }else{
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@""
                                                        message:@"出现错误"
                                                       delegate:nil
                                              cancelButtonTitle:NSLocalizedString(@"确定", nil)
                                              otherButtonTitles:nil];
        [alert show];
    }
}

3. 具体的VC中实现

调⽤SendRequest 的⽅法后会跳转到微博程序。

如果当前微博客户端没有账号,则进⼊登录界⾯;如果当前微博客户端已经有账户,则进⼊账户管理界⾯,选择要向第三⽅授权的账户。

当授权完成后会回调给第三⽅应⽤程序,第三⽅实现WeiboSDKDelegate 的
didReceiveWeiboResponse ⽅式监听此次请求的 response.
此中UserInfo内容为⽤户⾃定义(可不填写),微博回调Response中会 通过
requestUserInfo包含原 request.userInfo 中的所有数据,⽤于第三⽅⾃定义操作或request
区分。

<font color=#8E236B> 如果最后在实现微博SDK的回调中获得到 error_code=21338 并且出现sso package or login error那就是因为当前的Bundle ID和微博开放平台注册的应用的Bundle ID不一致导致的。 </font>

微博登录

#pragma mark - weibo sdk login
- (void)ssoButtonPressed{
    
    /*    SSO 授权认证(有客户端跳转,有网页打开)  */
    WBAuthorizeRequest *request = [WBAuthorizeRequest request]; //
    request.redirectURI = @"https://api.weibo.com/oauth2/default.html"; // 这里的redirectURL 需要与微博开放平台创建的应用的重定向地址一致
    request.scope = @"all";

    // request.userInfo 可不传  -- 在登录完成后会在回调中返回这里的数据,若未填写
    request.userInfo = @{@"ShareMessageFrom": @"WeiboViewController",
                         @"Other_Info_1": [NSNumber numberWithInt:123],
                         @"Other_Info_2": @[@"obj1", @"obj2"],
                         @"Other_Info_3": @{@"key1": @"obj1", @"key2": @"obj2"}};
    
    [WeiboSDK sendRequest:request];
}


#pragma mark NSNotification delegate login use
//登录的代理
- (void)weiboLoginByResponseInWBAuthorize:(NSNotification *)userInfo{
    
    WBAuthorizeResponse *response = userInfo.object;
    
    NSLog(@"log--微博登录代理:%@",response);
    
    // 可能需要使用到的参数
    NSString *wbtoken = [response accessToken];
    NSString *wbRefreshToken = [response refreshToken];
    NSString *wbCurrentUserID = [response userID];
    
    // 赋值
    self.wbtoken = wbtoken;
}
- (void)weiboWBSendMessageToWeiboResponse:(NSNotification *)userInfo{
    WBSendMessageToWeiboResponse *response = userInfo.object;
    
    NSString *accessToken = [response.authResponse accessToken];
    NSString *weCurrentUserID = [response.autoContentAccessingProxy userID];
}

微博登出 ++ 实现相应的 WBHttpRequestDelegate 代理方法

#pragma mark - weibo sdk log out
- (void)ssoOutButtonPressed
{
    if (self.wbtoken.length !=0 && self.wbtoken) {
        // 需要登录成功是时返回的token
        [WeiboSDK logOutWithToken:self.wbtoken delegate:self withTag:@"testUser"];
        
        // 在退出成功清空
        // 点击退出登录wbtoken清空
    }else{
        NSLog(@"您还未登录");
    }
    
}


#pragma mark WBHttpRequestDelegate -- log out use
- (void)request:(WBHttpRequest *)request didFinishLoadingWithResult:(NSString *)result
{
    NSString *trueStr = @"{\"result\":\"true\"}";
    if ([result isEqualToString:trueStr]) {
        self.wbtoken = nil; // 点击退出登录wbtoken清空
    }
    
    NSString *title = nil;
    UIAlertView *alert = nil;
    
    title = NSLocalizedString(@"收到网络回调", nil);
    alert = [[UIAlertView alloc] initWithTitle:title
                                       message:[NSString stringWithFormat:@"%@",result]
                                      delegate:nil
                             cancelButtonTitle:NSLocalizedString(@"确定", nil)
                             otherButtonTitles:nil];
    [alert show];
}

- (void)request:(WBHttpRequest *)request didFailWithError:(NSError *)error;
{
    NSString *title = nil;
    UIAlertView *alert = nil;
    
    title = NSLocalizedString(@"请求异常", nil);
    alert = [[UIAlertView alloc] initWithTitle:title
                                       message:[NSString stringWithFormat:@"%@",error]
                                      delegate:nil
                             cancelButtonTitle:NSLocalizedString(@"确定", nil)
                             otherButtonTitles:nil];
    [alert show];
}

微博分享 ++ 实现相应的 WBMediaTransferProtocol 代理方法

#pragma mark - weibo share message
- (void)shareButtonPressed{
    // 判断各种情况下是否可以发送 || 在实际使用中可以判定特定的对象是否为空来决定是否执行此次的分享功能
    if (!self.textSwitch.on && !self.imageSwitch.on && !self.mediaSwitch.on && !self.videoSwitch.on && !self.storySwitch.on) {
        return;
    }
    
    
    if ((self.textSwitch.on || self.mediaSwitch.on) && (!self.imageSwitch.on && !self.videoSwitch.on) && self.storySwitch.on) {
        // self.storySwitch.on 打开无意思作用
        //只有文字和多媒体的时候打开分享到story开关,只会呼起发布器,没有意义
        return;
    }
    self.messageObject = [self getMessageObject];
    
    if (!self.imageSwitch.on && !self.videoSwitch.on) {
        [self messageShare];
    }else
    {
        if (!_indicatorView) {
            _indicatorView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
            _indicatorView.center = self.view.center;
            [self.view addSubview:_indicatorView];
            _indicatorView.color = [UIColor blueColor];
        }
        
        [_indicatorView startAnimating];
        [_indicatorView setHidesWhenStopped:YES];
    }
    
}

- (WBMessageObject *)getMessageObject{
    WBMessageObject *message = [WBMessageObject message];
    
    if (self.textSwitch.on)
    {
        message.text = NSLocalizedString(@"这是测试一条通过WeiboSDK发送文字到微博--testDemo!", nil);
    }
    
    if (self.imageSwitch.on)
    {
        //        WBImageObject *image = [WBImageObject object];
        //        image.imageData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image_1" ofType:@"jpg"]];
        //        message.imageObject = image;
        
        UIImage *image = [UIImage imageNamed:@"WeiboSDK.bundle/images/empty_failed.png"];
        UIImage *image1 = [UIImage imageNamed:@"WeiboSDK.bundle/images/common_button_white.png"];
        UIImage *image2 = [UIImage imageNamed:@"WeiboSDK.bundle/images/common_button_white_highlighted.png"];
        NSArray *imageArray = [NSArray arrayWithObjects:image,image1,image2, nil];
        WBImageObject *imageObject = [WBImageObject object];
        if (self.storySwitch.on) {
            imageObject.isShareToStory = YES;
            imageArray = [NSArray arrayWithObject:image];
        }
        imageObject.delegate = self;
        [imageObject addImages:imageArray];
        message.imageObject = imageObject;
    }
    
    if (self.mediaSwitch.on)
    {
        WBWebpageObject *webpage = [WBWebpageObject object];
        webpage.objectID = @"identifier1";
        webpage.title = NSLocalizedString(@"分享网页标题", nil);
        webpage.description = [NSString stringWithFormat:NSLocalizedString(@"分享网页内容简介-%.0f", nil), [[NSDate date] timeIntervalSince1970]];
        webpage.thumbnailData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image_2" ofType:@"jpg"]];
        webpage.webpageUrl = @"http://weibo.com/p/1001603849727862021333?rightmod=1&wvr=6&mod=noticeboard";
        message.mediaObject = webpage;
    }
    
    if (self.videoSwitch.on) {
        WBNewVideoObject *videoObject = [WBNewVideoObject object];
        if (self.storySwitch.on) {
            videoObject.isShareToStory = YES;
        }
        NSURL *videoUrl = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"apm" ofType:@"mov"]];
        videoObject.delegate = self;
        [videoObject addVideo:videoUrl];
        message.videoObject = videoObject;
    }
    
    return message;
}

-(void)messageShare
{
    
    WBAuthorizeRequest *authRequest = [WBAuthorizeRequest request];
    authRequest.redirectURI = @"https://api.weibo.com/oauth2/default.html";
    authRequest.scope = @"all";
    
    WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest requestWithMessage:self.messageObject authInfo:authRequest access_token:self.wbtoken];
    request.userInfo = @{@"ShareMessageFrom": @"WeiboViewController",
                         @"Other_Info_1": [NSNumber numberWithInt:456],
                         @"Other_Info_2": @[@"obj1", @"obj2"],
                         @"Other_Info_3": @{@"key1": @"obj1", @"key2": @"obj2"}};
    if (![WeiboSDK sendRequest:request]) {
        [_indicatorView stopAnimating];
    }
}

#pragma mark WBMediaTransferProtocol -- share message use
-(void)wbsdk_TransferDidReceiveObject:(id)object
{
    [_indicatorView stopAnimating];
    [self messageShare];
}

-(void)wbsdk_TransferDidFailWithErrorCode:(WBSDKMediaTransferErrorCode)errorCode andError:(NSError*)error
{
    [_indicatorView stopAnimating];
}

还有微博 Link功能,主要可实现链接到某个特定的微博或者链接到某个用户的置顶微博,根据微博SDK给的接口可实现相应的链接功能。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容