新浪微博发送消息和授权机制原理(WeiboSDK)

1.首先是在微博发送消息,对于刚開始做weibo发送消息的刚開始学习的人会有一个误区,那就是会觉得须要授权后才干够发送消息。事实上发送消息仅仅须要几行代码就能够实现了,很easy,不须要先授权再发送消息,由于weibosdk已经帮我们封装好了。

(此情况须要用户安装client)

发送消息流程为:点击发送消息按键----SDK会自己主动帮我们推断用户是否安装了新浪微博client--假设未安装弹出安装提示----假设安装直接跳转到sina微博client进行发送----发送成功后自己主动跳回原应用程序。

1)在AppDelegate中注冊sdk, AppDelegate须要实现WeiboSDKDelegate

AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate, WeiboSDKDelegate>
{...

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //注冊SDK
    [WeiboSDK enableDebugMode:YES];
    [WeiboSDK registerApp:kAppKey];

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    return [WeiboSDK handleOpenURL:url delegate:self];
}

2)拼接消息对象WBMessageObject,并发送消息[WeiboSDK sendRequest:request];

WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest requestWithMessage:[self messageToShare]];
    request.userInfo = @{@"ShareMessageFrom": @"SendMessageToWeiboViewController",
                         @"Other_Info_1": [NSNumber numberWithInt:123],
                         @"Other_Info_2": @[@"obj1", @"obj2"],
                         @"Other_Info_3": @{@"key1": @"obj1", @"key2": @"obj2"}};
    //    request.shouldOpenWeiboAppInstallPageIfNotInstalled = NO;
    
    [WeiboSDK sendRequest:request];//这句就能够发送消息了,不须要先授权

- (WBMessageObject *)messageToShare
{
    WBMessageObject *message = [WBMessageObject message];
    
    if (self.textSwitch.on)
    {
        message.text = @"測试通过WeiboSDK发送文字到微博!";
    }
    
    if (self.imageSwitch.on)
    {
        WBImageObject *image = [WBImageObject object];
        image.imageData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image_1" ofType:@"jpg"]];
        message.imageObject = image;
    }

    if (self.mediaSwitch.on)
    {
        WBWebpageObject *webpage = [WBWebpageObject object];
        webpage.objectID = @"identifier1";
        webpage.title = @"分享网页标题";
        webpage.description = [NSString stringWithFormat:@"分享网页内容简单介绍-%.0f", [[NSDate date] timeIntervalSince1970]];
        webpage.thumbnailData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image_2" ofType:@"jpg"]];
        webpage.webpageUrl = @"http://sina.cn?

a=1"; message.mediaObject = webpage; } return message; }


重要:假设程序发送完消息无法跳回原应用的话是由于在plist文件里没有配置URL Types,appKey在你的新浪开发人员帐号里有。



2.授权。通过授权我们能够在用户未安装client的情况下关注指定微博。

授权主要是为了得到:userID,accessToken。有了accessToken我们就能够訪问新浪weibo的API了http://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPI



response.userInfo对象就是我们要的东西

#import <UIKit/UIKit.h>

@interface SinaWeiBoLoginViewController : UIViewController<UIWebViewDelegate>{
    UIWebView *_webView;
    void (^_completionHandler)(BOOL);
    BOOL loadSuccess;
}
@property (nonatomic, copy)void (^completionHandler)(BOOL);
@property (nonatomic)BOOL loadSuccess;

- (id)initWithLoginCompletion:(void (^) (BOOL isLoginSuccess))isLoginSuccess;
- (void)startRequest;
@end

//
//  SinaWeiBoLoginViewController.m
//  YinYin
//
//  Created by Lw. on 14-7-3.
//
//

#import "SinaWeiBoLoginViewController.h"
#import "SinaUtil.h"
#import "SVProgressHUD.h"

#define title_height ((!IS_IOS_7)?40:60)

@interface SinaWeiBoLoginViewController ()

@end

@implementation SinaWeiBoLoginViewController

@synthesize completionHandler,loadSuccess;

- (id)initWithLoginCompletion:(void (^) (BOOL isLoginSuccess))isLoginSuccess
{
    if (self = [super init]) {
        self.completionHandler = isLoginSuccess;
    }
    return self;
}

- (void)dealloc
{
    [_webView release];
    [super dealloc];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor whiteColor]];
    //自己定义导航
    UIView *customNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, title_height)];
    customNavBar.backgroundColor = [UIColor blackColor];
    [self.view addSubview:customNavBar];
    [customNavBar release];
    
    UIButton *returnBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [returnBtn setTitle:@"取消" forState:UIControlStateNormal];
    returnBtn.titleLabel.font = [UIFont systemFontOfSize:15];
    returnBtn.frame = CGRectMake(7, (!IS_IOS_7)?5:20, 50, 30);
    [returnBtn addTarget:self action:@selector(Cancelbtn) forControlEvents:UIControlEventTouchUpInside];
    [customNavBar addSubview:returnBtn];
    
	_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,title_height, self.view.frame.size.width, self.view.frame.size.height - title_height)];
	_webView.delegate = self;
	[self.view addSubview:_webView];
    [_webView release];
    [self startRequest];
}

-(void)Cancelbtn
{
    _webView.delegate = nil;
    if(self.completionHandler)
    {
        self.completionHandler(NO);
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}


#pragma mark - 请求网络

-(void)startRequest{
	NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[SinaUtil authorizeURL]];
	[_webView loadRequest:request];
}



#pragma mark - UIWebView代理方法
- (void)webViewDidStartLoad:(UIWebView *)webView{
    [SVProgressHUD show];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView{
    [SVProgressHUD dismiss];
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    [SVProgressHUD dismiss];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    if ([request.URL.absoluteString rangeOfString:@"code="].location != NSNotFound) {
        NSString *code = [[request.URL.query componentsSeparatedByString:@"="] objectAtIndex:1];
        loadSuccess = YES;
        if([SinaUtil getAccessToken:code]){
            if([SinaUtil sinaAtt]){
                [self dismissViewControllerAnimated:YES completion:^{
                    [SVProgressHUD showSuccessWithStatus:@"关注成功"];
                }];
            }else{
                [SVProgressHUD showErrorWithStatus:@"关注失败"];
            }
        }else{
            [SVProgressHUD showErrorWithStatus:@"授权失败"];
        }
        return NO;
    }
    return YES;
}
-(void)viewDidDisappear:(BOOL)animated{
    [SVProgressHUD dismiss];
}
-(void)viewDidUnload{
    [SVProgressHUD dismiss];
}
@end

#import <Foundation/Foundation.h>
#import "WeiboSDK.h"
#import "EnvConstant.h"
#import "ASIHTTPRequest.h"

@class ShareMultiple;


@interface SinaUtil : NSObject<WBHttpRequestDelegate>


+(void)share:(NSString *)text imageData:(UIImage *)imageData imageUrl:(NSString *)imageUrl url:(NSString *)url urlTitle:(NSString *)urlTitle urlDesc:(NSString *)urlDesc urlThumbdata:(UIImage *)urlThumbdata;

#pragma mark - public method
+(void)evaluatingJavaScriptFromString:(id)userInfo;

+(void)timerFireMethod:(NSTimer*)theTimer;

+(BOOL) startWith:(NSString*)prefix forString:(NSString*)text;
+(BOOL) stringEquals:(NSString*)str1 to:(NSString*)str2;

#pragma mark - 关注功能
/**
 *	授权地址
 *
 *	@return     UIWebView所要载入的url
 */
+ (NSURL *)authorizeURL;
+ (BOOL)getAccessToken:(NSString *)code;
+(BOOL)sinaAtt;
+(BOOL)isAuthorized;
+(void)saveLoginInfo:(NSDictionary *)aDic;

@end

#import "SinaUtil.h"
#import "EnvConstant.h"
#import "AppDelegate.h"
#import "WXApiObject.h"
#import "ASIHTTPRequest.h"
#import "SVProgressHUD.h"
#import "ASIHTTPRequest.h"
#import "ASIFormDataRequest.h"
#import "SBJSON.h"

@implementation SinaUtil

//3.公布媒体,仅仅能文字图片。文字媒体,无法文字图片媒体
+(void)share:(NSString *)text imageData:(UIImage *)imageData imageUrl:(NSString *)imageUrl url:(NSString *)url urlTitle:(NSString *)urlTitle urlDesc:(NSString *)urlDesc urlThumbdata:(UIImage *)urlThumbdata{
    
    WBMessageObject *message = [WBMessageObject message];
    //1.文本
    if(text != nil){
        message.text = text;
    }
    //2.图片和超链接
    if(imageData != nil){
        WBImageObject *imageObj = [WBImageObject object];
        imageObj.imageData = UIImagePNGRepresentation(imageData);
        message.imageObject = imageObj;
    }else if (imageUrl != nil){
        if([@"http://www.yypt.com/home/resources/images/activity/weiboshare.jpg" isEqualToString:imageUrl]){
            WBImageObject *imageObj = [WBImageObject object];
            imageObj.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"weiboshare.jpg"]);
            message.imageObject = imageObj;
        }else{
            //message.text = [NSString stringWithFormat:@"%@%@",message.text,imageUrl];
        }
}
    //3.媒体
    if(url != nil){
        WBWebpageObject *webpage = [WBWebpageObject object];
        webpage.objectID = @"identifier1";
        webpage.title = urlTitle;
        webpage.description = urlDesc;
        webpage.thumbnailData = UIImagePNGRepresentation(urlThumbdata);
        webpage.webpageUrl = url;
        message.mediaObject = webpage;
    }
    WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest requestWithMessage:message];
    [WeiboSDK sendRequest:request];
}

#pragma mark - WBHttpRequestDelegate
- (void)request:(WBHttpRequest *)request didFinishLoadingWithResult:(NSString *)result{
    //收到网络回调
}

- (void)request:(WBHttpRequest *)request didFailWithError:(NSError *)error;{
    //请求异常
}

#pragma mark - public method
//运行脚本
+(void)evaluatingJavaScriptFromString:(id)userInfo{
    [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(timerFireMethod:) userInfo:userInfo repeats:NO];
}
//timer回调,0成功,1失败,2取消
+(void)timerFireMethod:(NSTimer*)theTimer{
    if([theTimer.userInfo isKindOfClass:[SendMessageToWXResp class]]){
        SendMessageToWXResp* response = (SendMessageToWXResp *)theTimer.userInfo;
        int d = 0;
        switch (response.errCode) {
            case WXSuccess:
                d = 0;
                break;
            case WXErrCodeUserCancel:
                d = 2;
                break;
            default:
                d = 1;
                break;
        }
        NSString* jsString = @"$(document).trigger('shareResultEvent',['%d'])";
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
        [appDelegate.viewController.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:jsString,d]];//这里的errcode不同于weibo的statusCode
        
    }else if([theTimer.userInfo isKindOfClass:[WBBaseResponse class]]){
        WBBaseResponse* response = (WBBaseResponse *)theTimer.userInfo;
        int d = 0;
        switch (response.statusCode) {
            case WeiboSDKResponseStatusCodeSuccess:
                d = 0;
                break;
            case WeiboSDKResponseStatusCodeUserCancel:
                d = 2;
                break;
            default:
                d = 1;
                break;
        }

        NSString* jsString = @"$(document).trigger('shareResultEvent',['%d'])";
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
        [appDelegate.viewController.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:jsString,d]];
    }
    

}
#pragma mark - string
+(BOOL) startWith:(NSString*)prefix forString:(NSString*)text{
    if ( text != nil && prefix != nil ){
        if ( [prefix length] > [text length] ) {
            return NO;
        }
        
        NSString* prestr = [text substringToIndex:[prefix length]];
        if ( [self stringEquals:prestr to:prefix] ) {
            return YES;
        }
        
    }
    return NO;
}
+(BOOL) stringEquals:(NSString*)str1 to:(NSString*)str2
{
    if ( str1 == nil || str2 == nil ) {
        return NO;
    }
    return [str1 compare:str2 options:NSCaseInsensitiveSearch] == NSOrderedSame;
}

#pragma mark - 关注功能
/**
 *	授权地址
 *
 *	@return     UIWebView所要载入的url
 */
+ (NSURL *)authorizeURL
{
    NSString *authStr = [NSString stringWithFormat:@"%@?client_id=%@&redirect_uri=%@&response_type=%@&display=%@",SINA_AUTHORIZE_URL,kWBSDKDemoAppKey,wbkRedirectURI,@"code",@"mobile"];
    return [NSURL URLWithString:authStr];
}

/**
 *	获取AccessToken
 *
 *	@param	code        在webView的重定向地址中取得code
 *  @param  isSuccess   block 请求成功的回调
 *                      BOOL  isSuccess 请求是否成功 YES or NO
 */
+ (BOOL)getAccessToken:(NSString *)code{
    NSURL *url = [NSURL URLWithString:[HOSTURL stringByAppendingString:@"/oauth2/access_token"]];
    ASIFormDataRequest *request = [[ASIFormDataRequest alloc]initWithURL:url];
    [request addPostValue:kWBSDKDemoAppKey forKey:@"client_id"];
    [request addPostValue:kWBSDKDemoAppSecret forKey:@"client_secret"];
    [request addPostValue:@"authorization_code" forKey:@"grant_type"];
    [request addPostValue:code forKey:@"code"];
    [request addPostValue:wbkRedirectURI forKey:@"redirect_uri"];
    [request setRequestMethod:@"POST"];
    [SVProgressHUD show];
    [request startSynchronous];

    NSError *err = [request error];
    BOOL flag = NO;
    if (!err) {
        NSString *responseString = [request responseString];
        NSLog(@"responseString = %@", responseString);
        if ([responseString rangeOfString:@"access_token"].location != NSNotFound) {
            SBJSON *json = [[SBJSON alloc] init];
            NSDictionary *jsonDic = [json objectWithString:responseString];
            [SinaUtil saveLoginInfo:jsonDic];
        }
        flag = YES;
    }else{
        flag = NO;
    }
    [SVProgressHUD dismiss];
    return flag;
}

//关注微博
+(BOOL)sinaAtt{
    NSString *accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:SINA_ACCESS_TOKEN_KEY];
    NSString *path = @"/2/friendships/create.json";
    NSString *requestUrl = [HOSTURL stringByAppendingString:path];
    NSLog(@"requestUrl = %@",requestUrl);
    ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:requestUrl]];
    [request addPostValue:accessToken forKey:@"access_token"];
    [request addPostValue:ATTENTION_SINA_WEIBO_NUM forKey:@"uid"];
    [request addPostValue:ATTENTION_SINA_WEIBO_SCREEN_NAME forKey:@"screen_name"];
    [request startSynchronous];
    request.timeOutSeconds = 6;
    NSError *error = [request error];
    BOOL flag = NO;
    if(error!=nil){
        flag = NO;
    }else{
        flag = YES;
    }
    return flag;
}

/**
 *	推断有没有登录过,而且获得到的token有没有过期
 *
 *	@return     YES 有可用的token ,而且没有过期; NO 没有可用的token
 */
+(BOOL)isAuthorized{
    NSUserDefaults *userDef = [NSUserDefaults standardUserDefaults];
    NSString *accessToken = [userDef objectForKey:SINA_ACCESS_TOKEN_KEY];
    NSDate *expiresDate = [userDef objectForKey:SINA_ACCESS_EXPIRES_IN_KEY];
    if (expiresDate){
        return (NSOrderedDescending == [expiresDate compare:[NSDate date]] && accessToken);
    }
    return NO;
}

/**
 *	保存登录信息
 *
 *	@param	aDic	字典中有access_token,exoires_in,uid等信息
 */
+(void)saveLoginInfo:(NSDictionary *)aDic{
    NSLog(@"保存token...");
    [[NSUserDefaults standardUserDefaults] setObject:[aDic objectForKey:@"access_token"] forKey:SINA_ACCESS_TOKEN_KEY];
    NSDate *expiresDate = [NSDate dateWithTimeIntervalSinceNow:[[aDic objectForKey:@"expires_in"] intValue]];
    [[NSUserDefaults standardUserDefaults] setObject:expiresDate forKey:SINA_ACCESS_EXPIRES_IN_KEY];
    [[NSUserDefaults standardUserDefaults] setObject:[aDic objectForKey:@"uid"] forKey:SINA_USER_ID_KEY];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

@end

调用方式:

if([SinaUtil isAuthorized]){
                if([SinaUtil sinaAtt]){
                    [SVProgressHUD showSuccessWithStatus:@"关注成功"];
                }else{
                    [SVProgressHUD showErrorWithStatus:@"关注失败"];
                }
            }else{
                //[self selectRow:@"follow-wb"];
                SinaWeiBoLoginViewController *sinaVC = [[SinaWeiBoLoginViewController alloc]init];
                [self presentViewController:sinaVC animated:YES completion:nil];
            }













原文地址:https://www.cnblogs.com/cxchanpin/p/6882574.html