新浪微博最新 SDK 编程思路

// 是否为iOS7

#define iOS7 ([UIDevice currentDevice].systemVersion.doubleValue >= 7.0)

// 是否为4inch

#define FourInch ([UIScreen mainScreen].bounds.size.height == 568.0)

// 工程当中添加的 AppIcon 等图片无法显示

右键定位到图片路径,打开当前目录下的 Contents.json 从其他代码处拷贝图片属性即可(2x 对应2x,4R 对应4R)



1️⃣ 首页
自定义 Tabbar 替换系统原有的 TabBar,frame 设置相同,然后移除系统的.
自定义一个 TabBarViewController 类继承TabBarViewController,在此类中创建需要添加4个UITableViewController 的自定义类,分别为"首页","消息","广场","我".
在处理按钮点击图片的时候,如果是iOS7就不需要渲染按钮图片 imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal 
自定义 TabBarButton 重写

imageRectForContentRect:

titleRectForContentRect:

方法来重新布局内部图片和文字,最后在

initWithFrame 

中把图片和文字设置居中,再添加到自定义的 TabBar 上.

setHighlighted: 记得重写此方法用来清除系统原有的设置(此方法什么都不写)

TabBarController 上切换视图还是必须要交给此控制器,所以此控制器要和 TabBar 绑定代理关系,当 TabBar 监听到按钮事件后,通过代理让控制器调用切换视图(视图预先被添加到数据中,通过tag 值来判断从哪个视图跳转到哪里)

添加顶部的导航控制器,让 TabBarController 切换的是导航栏控制器,给控制器包装一个控制器,这样上面才有导航栏,每一个页面的导航栏都是不同的

自定义导航控制器,把有关导航控制器的所有内容封装到一起(包含主题等)

导航栏主题只用设置一次全局都生效,设置主题应该写到 initialize 中,此方法第一次使用此类的时候才会调用,viewDidLoad 中会被调用4次,会产生不必要的性能浪费

每一个控制器的左上角都又一个返回箭头

在 initialize方法中:

1️⃣ 设置导航栏主题

[UINavgationBar appearance]; // 获得主题

setBackgroundImage: // 设置背景(新浪只有 iOS6背景图片,iOS7是系统默认的白色)

2️⃣ 设置导航栏标题文字样式

[navBar setTitleTextAttributes:
字体很粗是因为带有阴影,需要除去阴影(文字有偏差,要矫正偏差为0)
UIOffset
[NSValue valueWithUIOffset:UIOffsetZero // 设置偏差为0

为消息控制器添加 写私信 按钮,需要适配 iOS6
需要拿到导航栏按钮主题,默认私信按钮不可用,设置监听方法,此方法没被调用就说明不可用
.enable = NO;

在广场顶部放入一个搜索框
.titleView
iOS 6中的默认搜索框样式无法满足需求,新浪有提供图片
设置背景图片也无法满足,不能继承 UISearchBar(边框有圆角)
可以继承 UITextFiled ,在初始化完成的时候设置
1️⃣ 背景: .background 会被拉伸,设置一个UIImage分类,指定拉伸中间局部
[image stretchableImageWithLeftCapWidth: topCapHeight:
2️⃣ 文字居中: .textAlignment(无法满足,是居中的) 子类无法满足就去 父类UIControl找
UIControlContentVerticalAlignment // 水平
添加右上角清除按钮 .clearButtonMode
还需要添加放大镜按钮 通过 init 创建的控件没有宽高,用 initWithImage:有宽高
UIView 有一个属性 leftView,需要和右边按钮一样,设置模式,永远显示
.leftViewMode = UITextFileldViewAlways
// 设置.ContentMode .width 就可以让放大镜完美显示
.placeholder 添加背景文字(搜索)

自定义首页顶部按钮
高亮的时候 view 不变灰色
.adjustsImageWhenHight
自定义的目的就是把图片放在文字的左边
顶部的文字有可能变化,需要设定成根据文字的宽度去调整按钮文字的宽度
点击标题要修改箭头的方法 titleButton.currentImage == [UIImage imageWithName:@"图片名"];
下拉产生一个菜单,.centerX 是当前view 宽度的一半效果就很好
利用 quartz2D 拉伸图片(新浪提供 menu 图片)
1️⃣ 创建 menu 继承 UIVIew
2️⃣ 把图片画出来
3️⃣ 在初始化方法中清楚背景色
拉伸的时候不能拉伸中间箭头部分,应该拉伸图片的最左边或者最右边(拉伸某一边的时候也要保护另一边的图片)
目前弹出来的菜单会随着 tableView 滚动
所以一旦但出来菜单,禁止 tableView 滚动 .scrollEnabled(不能禁止交互,禁止后菜单也无法响应)

添加首页左右按钮
用此方法添加initWithCustomView:(创建的 button)
弹出菜单的父类是 tableView,把菜单 Y 坐标上移会造成箭头被遮盖
所以要把菜单添加到.window上

需要删除系统自带的 tabbar 上的按钮,在 viewWillAppear: 中判断是否是 UIControl 类(UITabBarButton 是私有 API,无法调用),是的话就删除,这样系统的 tabbar 上的 buttonitem 就被移除了
重写导航栏的导航方法在里面把 push 时候隐藏导航栏设置为 YES,但要在 controllers>0的时候(栈顶)
当controllers>0的时候 才设置左上角有返回按钮
手势返回上一页,默认是开启的,自定义的 item 就没有此效果了.
.interactivePopGestureRecognizer.delegate = nil 就可以了(iOS7 SDK)

版本新特性:
第一次运行这个版本就会展示新功能介绍
对比上一次运行的版本记录,记录保存到沙盒中
沙盒存储->不存在的话就存储当前软件版本->NewfeatureViewController->开始微博->TabBarController
                -> 存在的话 当前>此前存入的 ->
在 AppDelegate 中判断 self.window.rootViewController 的根控制器
.plist 中 Bundle Version 就可以更新 App Store
[NSBundle mainBundle].infoDictionary 就可以直接获取工程属性文件
取出对应的版本号: CFBundleVersion(key) 转换成 double 即可
当版本号为 1.1.2 时候就无法转换成 double,可以转换成字符串
使用 [NSUserDefault standardUserDefault stringForKey:存储
[currentVersion compare:sandBoxVersion == NSOrderDescending (降序) 左边大
开始展示新特性控制器,然后存储当前软件的版本号,方便下一次对比
[default synchronize] 记得同步(立即存储)

CFStringRef   Core Foundation
NSString  Foundation
通过桥接可以互相转换, (__bridge NSString *)kCFBundleVersionKey
展示页面:
scrollView 
设置 contentSize 才能滚动(图片个数 * 图片宽度)
去掉滚动条 .showHorizontalScrollIndicator = NO
设置 page 翻页
.currentPageIndicatorTintColor 圆点颜色
.pageIndicatorTintColor (189,189,189)
把计算出来的 pageNumber 设置成 double,四舍五入(+0.5)然后强转成 int

可以打勾的按钮为 checkbox(业内俗称)
不能使用 lastObject 查询 scrollView 的最后一个视图.因为scrollView 中自己的子控件就很多(滚动条等),应该在遍历创建的时候通过 i 值取判断最后一个视图,在上面创建按钮(分享,开始新版本)
按钮的坐标通过乘系数(0.5,0.6等)可以适配屏幕大小,按钮是添加到 imageView 上的,默认是不能交互的,需要手动开启

控件不能响应的几点:
1️⃣ 控件自己的 Enabled
2️⃣ 父控件的 enabled
3️⃣ 按钮的 enable或userInteractionEnabled
4️⃣ 控件不在父控件的边框范围内(点击的时候是父事件传递给子事件的)

button:
 imageEginsets // 按钮图片内边框
 titleEginsets //按钮文字内边框
 contentEginsets //按钮内边框
设置边框后 内部的内容会被压缩
可以给图片和文字之间设置间距,这样之间就有间隔了

新特性展示完毕后进入主页面:
1.push  无法销毁之前的控制器
2.modal 无法销毁之前的控制器
3.切换 window 的根控制器  可以销毁
推荐第3种
修改.keyWindow.rootViewController

iOS6 目前新特性的页面不是480高度,是460,图片被压缩了,Application 中设置状态栏为 NO设置的太早了,应该修改为在显示 Tabbar 控制器的时候再设置为 NO
在开始微博的响应事件中 设置显示状态栏
iOS7 是一直显示的,不用管理

现在4inch 的时候新特性展示视图图片被拉伸了,系统并没有自动加载@2x 4inch(系统自动加载的只有程序启动图片,剩余的图片需要自己手动取加载)
判断是否是 4inch 是的话字符串追加-568h(@2x 是自动的)
运行发现屏幕无图片展示,原因是在图片文件中底部需要手动设置此图片的屏幕配对4inch(Xcode LaunchImage 中设置,默认显示未赋值状态)

用户访问新浪微博
OAuth 授权(资源授权)
1️⃣ 应用要想访问用户数据需要资源授权
2️⃣ 这样程序就可以直接和新浪数据库链接
需要 1️⃣ 成为新浪开发者 open.weibo.com
        2️⃣ 让用户输入帐号密码授权
OAUth授权步骤:
第三方访问服务商用户资源就需要
1️⃣ 先获得未授权的 Requset Token (就是登录页面,新浪提供的页面,WebView, api.weibo.com/oauth2/authorize,两个参数,client_id appKey(让新浪知道是哪个应用) , redirect_uri 回调地址)
2️⃣ 获得用户的 Request Token(网址后面会有得到的字符串)
3️⃣用授权的 Request Token 换取 Access Token(就是一串字符串)
使用 POST 请求,URL=api.weibo.com/oauth2/access_token
5个参数
id 应用 Key,secret应用 secret,type 使用 authorized_code ,uri 回调地址
code 授权后的 code
全部过程很安全,从头到尾不知道用户的帐号密码
注意点:
回调地址参数必须是开发者填写的网址,不然提示回调地址不匹配
测试帐号授权只有15+1个(自己),通过审核后就可以不受限制
测试帐号只有一天有效期(自己的时间很长)
创建一个新的视图控制器用来加载 WebView

webview有个代理方法,监听状态,shouldStartLoadWithRequest:每当发送请求之前都会调用此方法
返回值是 BOOL,询问本次链接是否可以加载,这个方法中可以得到本次请求的链接地址
判断请求是否是回调地址就取出链接的字符串, .url.absoluteString
url rangeOfString: @"code="   检测这串是否存在 找到的话 NSRange 中length location 中都有值
if(range.location != NSNotFound) // 找到
{
int fromIndex = range.location + range.length;
NSString *code = [url substringFromIndex:fromIndex]; //得到 code 字符串
3️⃣ 利用 code 换取 accessToken(访问标记)
post请求=路径(新浪提供网址链接)+参数(5个,新浪提供参数名称)
利用 AFN 框架发送 POST(ASI 已停止更新)
POST:
0️⃣ 请求地址
1️⃣ 封装请求参数
❗️ 封装成字典(注意包装成字符串)
2️⃣ 请求成功回调
3️⃣ 请求失败回调
然后把回调页面设置为 NO(移动客户端不需要)
}

开始请求后,报错1016(content-type:text/plain)报错信息,新浪只告诉我们返回是普通文本,并不告诉我们是 JSON 还是 XML
需要手动说明接收此类型数据,  .responseSerializer.acceptableContentTypes = [NSSet setWithObject:] 或者直接修改源代码(215行代码添加 text/plain类型)

请求成功,新浪返回给我们4个参数(新浪提供名称)
access_token(重点,相当于帐号密码)
expires_in(单位为秒,授权有效期)(自己的授权是4.9年)
remind_in(此参数即将废弃,不推荐使用,推荐用 expires_in)
uid(数据库的标识)

access_token 一个用户给一个应用授权成功就能获取一个对应的
一个用户对应一个 uid
也就是说一个 access_token 关联一个用户和一个应用

用 AFN 框架简化请求和返回值了,本来返回的是 NSData 要拼接和转换成字典,现在直接是字典
面向模型开发,把得到的字典转换成模型,好处就是将来取出来的时候就是模型
转换完成后 归档模型 archiveRootObject: toFile:
<NSCoding>  encodeWithCider: 当把一个对象归档到文件中会调用一次
initWithCoder: 从一个文件中解析一个对象会调用

在 AppDelegate 中取出帐号,判断模型是否存在,存在就是上次授权成功了

工具类:屏蔽业务细节:
新建控制器工具类,帮助选择控制器
工具类也可以辅助管理帐号,得到和存储就可以交给工具类

❗️ 注意点就是 self.window makekeyanddisplay 这句要放置到前面,否咋其他类的 window 为 nil

新增一个属性,用来计算出具体的授权过期的时间,然后compare比较当前事件和过期时间,返回NSOrderedAscending(过期)

拿到存储的 access_token 提交给新浪换取用户数据
首页展示 个人和关注的人的数据
发送 GET 请求,成功会得到微博数组,数组名为 statuses
修改 count 得到返回的数据条数(默认20,最大100)

tableView 的 cell 每一个 cell 都有子线程取下载图片,当缓存 cell 的时候子子线程会错乱
cell 图片 -> 手机缓存(内存缓存和硬盘缓存) <-> 新浪服务器下载
所以采取框架 SDWebimage,可以防止主线程下载图片,卡住主线程,造成滚动延迟
使用此框架的时候建议在 AppDelegate 中监听内存警告,清除内存缓存(不是硬盘缓存)
框架方法 cancelAll  //先取消所有下载请求
                imageCache clearDisk //清除硬盘
                                      clearMemory //清除内存(这种)

越早发送的微博 ID 越大,新的微博就在前面

tableview集成刷新控件
uirefrescontrol
要先取出最新的一条的 微博id,然后赋值给 since_id 重新请求就可以刷新
但是这样会被覆盖旧数据,创建一个新数组填充最新的微博,然后把此数组再添加到原有的数组中
但是这样新数据是在数组的最后面的,所以要创建一个临时的数组先添加新数组再添加旧数组,然后在把临时数组赋值给大数组

加载更旧的数据
上拉刷新,(MJ 控件)

自定义 cell
1️⃣ 添加所有需要的子控件
2️⃣ 将模型数据显示到子控件
3️⃣ 根据模型数据计算子控件的 frame 并设置
cell 拥有一个 frame 模型,不要直接拥有数据模型

cell 模型          frame模型(得到微博数据模型)     
cell(frame) -> frame(status) ->Status(微博)

自定义cell 的initWithStyle 中初始化
1️⃣ 添加顶部控件
2️⃣ 添加底部工具条(转发,赞,评论)
所有的控件都添加到 cell 的 contentView上
新浪的顶部是一个白色控件,转发是一个灰色控件

系统的时间会影响新浪微博计算时间差(刚刚,1min 前)

尾巴来源属性 在 get 方法中 substringwithrange:来截取(>   </ 通过这两个符号可截取)新浪返回给我们的字符串
时间分为今天/昨天/今年/非今年
nscalendar 专门用来比较时间的类
nsstring 转 nsdate 利用nsdateformatter datefromstring:
如果是真机 必须加上这句 .local = initwithlocaleidentifier:@"en_US"//告诉系统是什么格式的时间
nsdatecompoents deltawithnow
然后根据差距返回对应字符串
目前的问题是已经计算出来的时间无法自动更新宽度显示(会自动变成时间格式,无法显示完成)
每次拖动 cell 都会重新调用时间的 set 方法,宽度需要重新计算(目前只计算了一次)

会员判断
mbtype 会员类型(年费) mbrank 会员等级
mbtype > 2就是会员

转发微博
涉及到图文混排(暂不处理),转发人的名称是一个按钮也设计到图文混排,暂不处理,只显示转发的微博即可
目前只显示 被转发人的名称和微博

图层分布
上:原创微博
中:转发微博
下:赞按钮
判断是否有转发微博,有的话就改变 frame 没有加高 frame
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值