新浪微博demo文档
制作:杨江桦
第一步:授权
目前新浪微博开放平台用户身份鉴权有OAuth2.0和Basic Auth(仅用于应用所属开发者调试接口),新版接口也仅支持这两种方式。
(来自新浪微博关于授权说明文档)
这里使用OAuth2.0的方式。具体操作如下:
通过OAuth2的authorize接口
https://api.weibo.com/oauth2/authorize
来获取code字段,里面包含有以后必须使用的access token.
参数传递的方式如下:
NSString *urlString = @"https://api.weibo.com/oauth2/authorize?client_id=2413670638&redirect_uri=http://www.baidu.com&response_type=code&display=mobile&state=authorize";
NSURLRequest *request= [[NSURLRequestalloc] initWithURL:[NSURLURLWithString:urlString]];
[self.webViewsetDelegate:self];
[_webView loadRequest:request];
这时授权后,会重定向到一个URL,这个URL就包含了Code字段,此时截取这个字段的信息,补充到accesstoken那个API的后面进行调用,从下载的数据中获取accesstoken.截取数据段可以用NSRange的方式来截取,我们只要输出一次返回的数据,观察它的特点,就能找到简单截取的方法,这里略去。下载数据的方法如下:
NSMutableString *muString= [[NSMutableStringalloc] initWithString:@"https://api.weibo.com/oauth2/access_token?client_id=2413670638&client_secret=ca1d709aec3fc03a96cf56d81086f56a&grant_type=authorization_code&redirect_uri=http://www.baidu.com&code="];
[muString appendString:codeString];
//第一步,创建URL
NSURL *urlstring = [NSURLURLWithString:muString];
//第二步,创建请求
NSMutableURLRequest *request = [[NSMutableURLRequestalloc]initWithURL:urlstringcachePolicy:NSURLRequestUseProtocolCachePolicytimeoutInterval:10];
[request setHTTPMethod:@"POST"];//设置请求方式为POST,默认为GET
NSString *str = @"type=focus-c";//设置参数
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]; //将参数转换成data类型的数据
[request setHTTPBody:data]; //设置参数
//第三步,连接服务器
NSData *received = [NSURLConnectionsendSynchronousRequest:request returningResponse:nil error:nil];
NSError *error = nil;
NSDictionary *dictionary = [NSJSONSerializationJSONObjectWithData:received options:kNilOptions error:&error];
[[NSUserDefaults standardUserDefaults] setObject:[dictionaryobjectForKey:@"access_token"]forKey:@"access_token"];
[[NSUserDefaults standardUserDefaults] synchronize];
代码的注释已经很清楚了,主要就是利用URL下载数据,取得access token,然后通过NSUserDefaults的方式存放好,方便以后调用。返回的字段中还有uid,这个参数非常有用,所以同样用保存access token的方式保存下来以便以后使用,于此授权结束。
补充说明一下设定参数的方法,就是在对应API的url后面添加 “?参数1=&参数2=&参数3=………”。这样建立连接后就可以下载到对应的信息,然后初始化出来就可以了。
第二步:页面设计
本来对微博并不了解,所以专门去开了一个账号,然后刷了几天的微博,其实微博的内容大致也比较了解了。我的微博,热门微博这些都属于微博的页面,可以归为一类;而另一类就是关注与被关注,粉丝页面等。我的初始设计是,关注人的微博页面——我的微博页面——关注页面——互相关注页面。设计是关注人的微博页面可以看到微博,可以评论转发,我的微博页面可以看到自己的微博,同样可以评论转发,关注页面就可以看到自己关注的人,点击进去可以看到对应关注人发的微博,而互相关注页面可以看到互相关注的人,也可以看到互相关注的那个人的微博。疏忽大意,就这样开始做了,直到最后才发现,没有根据用户的id直接可以找到他发的微博的API,所以被迫改为点击关注人,显示其详细信息,要吸取这次教训,以后先观察好能否实现再动手。
那么现在先贴出设计的页面:
第三步,制作首页,“关注用户的微博”页面
查看官方的API文档就可以找到,
statuses/friends_timeline
获取当前登录用户及其所关注用户的最新微博
对应的接口是
https://api.weibo.com/2/statuses/friends_timeline.json
然后查看一下请求的参数:请求参数
| 必选 | 类型及范围 | 说明 |
source | false | string | 采用OAuth授权方式不需要此参数,其他授权方式为必填参数,数值为应用的AppKey。 |
access_token | false | string | 采用OAuth授权方式为必填参数,其他授权方式不需要此参数,OAuth授权后获得。 |
since_id | false | int64 | 若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0。 |
max_id | false | int64 | 若指定此参数,则返回ID小于或等于max_id的微博,默认为0。 |
count | false | int | 单页返回的记录条数,最大不超过100,默认为20。 |
page | false | int | 返回结果的页码,默认为1。 |
base_app | false | int | 是否只获取当前应用的数据。0为否(所有数据),1为是(仅当前应用),默认为0。 |
feature | false | int | 过滤类型ID,0:全部、1:原创、2:图片、3:视频、4:音乐,默认为0。 |
trim_user | false | int | 返回值中user字段开关,0:返回完整user字段、1:user字段仅返回user_id,默认为0。 |
其实我们主要需要填的参数是,accesstoken,page就可以了。其他的参数,如count可以根据自己的需要设定,设定方法和之前一样。
这里专门为微博设置了一个类,从返回的数据中保存微博的各种信息,然后用一个数组把各个cell的微博保存起来。对应的条数就对应着对应的行。
具体可以查看代码。
在viewDidLoad中调用下载的函数,下载完数据保存在数组后,就可以在cellforRowAtIndex里面通过行数引用对应的微博,并且设计各种label和imageview来显示这些微博的数据。具体位置是通过调试不断调整到合适的。
设计了两个按钮,一个是“评论”,一个是“转发”,后面再补充他们的页面。先设置好,暂时不写响应。
高度的设计是最麻烦的。设计的地方时heightforRowAtindex,由于直接加载图片的话,程序会变得非常的卡。被迫只能异步下载。但是异步下载图片必然无法知道它的高度,所以只能选取一个合适的静态高度,再结合各种label的高度,最终设置出合适的高度。这部分可以自己设置,也可以参考我的代码,我的看法是图片的高度大约占半个cell要合适一点,所以我一般弄好各个label之后再根据实际情况作调整。
最后就是add到对应的cell即可。至此,这一部分算是做完了。而对应的我的微博的部分,只是API的调用上不同,把API换为https://api.weibo.com/2/statuses/user_timeline.json,对应的参数可以自己调整。就可以得到对应返回的结果,显示的方式和我关注的微博一致。
这两个页面处理刷新的方法也是一样的,只要判断内容到达了底部,就可以进行刷新,只要把对应的参数page + 1,再下载数据reload一次就可以刷新到下面。处理cell重用的问题,有几个方法,可以看我的博客转发的关于cell重用处理的问题。
第三步:评论和转发页面
这两个页面都是需要调用写入接口的。写入的方式为POST。所以代码和之前有所不同。看看调用API的代码如下:
NSString *paramString = [NSStringstringWithFormat:@"comment=%@&id=%lld&access_token=%@",content,_weiboID,[infoOfWeiboreturnAccessToken]];
NSLog(@"paramString = %@",paramString);
NSMutableData *postCommentData= [[NSMutableDataalloc]init];
[postCommentData appendData:[paramStringdataUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest *request = [NSMutableURLRequestrequestWithURL:[NSURLURLWithString:@"https://api.weibo.com/2/comments/create.json"]cachePolicy:NSURLRequestReloadIgnoringCacheDatatimeoutInterval:5.0];
[request setHTTPMethod:@"POST"]; //设置数据请求方式为post
[request setHTTPBody:postCommentData]; //设置参数
self.connection = [[NSURLConnectionalloc] initWithRequest:requestdelegate:selfstartImmediately:YES];
把参数单独分离出来如:
NSString *paramString = [NSStringstringWithFormat:@"comment=%@&id=%lld&access_token=%@",content,_weiboID,[infoOfWeiboreturnAccessToken]];
然后建立请求,请求的URL就是对应的API,然后set写入的方式为POST,然后set参数为上面设置好的参数。然后建立连接,startImmediately为YES就立刻响应,发送数据。内容就是上面的参数comment,这些可以查看API文档的说明。
转发的方法也是差不多了,只要看清楚API和需要的参数即可。
补充说明一点就是评论和发微博等都需要限定字数,但是转发就不一定,转发不能超过140个字,但可以为0,因为没有写内容,会有个默认参数是补充这点的,默认的参数是“转发微博”。
发微博的方法也一样,这里就不在赘述。
最后一点:参数的传递和其他说明
大部分参数的传递利用的segue,方法如下:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifierisEqualToString:@"SendComment"]) {
//sendcomme *vc = [seguedestinationViewController];
SendCommentViewController *vc = [seguedestinationViewController];
vc.weiboID = self.SentWeiboID.longLongValue;
}
}
这样就是把这个页面的SentWeiboID参数传给了下个页面的weiboID。还有一种方法就是,
UITableViewController *send = segue.destinationViewController;
if ([segue.identifierisEqualToString:@"ShowOne"]) {
if ([send respondsToSelector:@selector(setData:)])
[send setValue:i.profileImageURLforKey:@"ImageUrlString"];}
这样设置了目的控制器,然后还是通过segue传参,方法是setData,就可以把上面的i.profileImageURl这个参数传给后一个页面的ImageUrlString。不过目前只测试过NSstring类型的数据可以,其他的还没发现可以传递的,所以传递的时候总是要先把数据转化为对应的String,然后再用xxxx.xxxxvalue的方式获取需要的类型。如ask.floatvalue就可以获取其对应的float的值。可以NSlog出来测试一下。
我的微博和关注的微博这些页面的评论可以用同一个页面,只是参数不同即可,转发也同理。
关注页面选择点击一行进入详细信息时,可以设置一个参数保存当前行,在didselect。。。那个函数里面用一个变量保存好indexpath.row 就可以了,然后就是利用这个行号把详细数据弄出来,这部分比较简单。
总结:
1,本来对ios的了解十分浅陋,上学期上课学到的东西原来只是九牛一毛,在真正实践的时候出现了很多问题,直到现在,也依然有一大堆问题没有处理好,比如下载数据,同步异步的选择等等,需要继续学习。
2,这个工程有用到手动的,有用到storyboard直接建立的控件,感觉手动建立的更加灵活,而用storyboard的难免会出现一些调整困难的问题。
3,需要继续补充对应的OC语言的知识,有很多内存管理方面的内容不理解。设计的方法有很多缺陷,控件的作用不够了解。总体的机制都不甚了解。越接触越发现有很多东西没学好。所以以后要加倍努力学习和练习。
报告结束。以后有时间会不断继续修改这个程序,希望可以得到更好的锻炼,以此进步。