日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

IOS第四天-新浪微博 -存储优化OAuth授权账号信息,下拉刷新,字典转模型

發(fā)布時(shí)間:2025/7/25 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IOS第四天-新浪微博 -存储优化OAuth授权账号信息,下拉刷新,字典转模型 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

*************application

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// 1.創(chuàng)建窗口self.window = [[UIWindow alloc] init];self.window.frame = [UIScreen mainScreen].bounds;// 2.設(shè)置根控制器HWAccount *account = [HWAccountTool account];if (account) { // 之前已經(jīng)登錄成功過(guò) [self.window switchRootViewController];} else {self.window.rootViewController = [[HWOAuthViewController alloc] init]; //授權(quán)登陸的界面}// 3.顯示窗口 [self.window makeKeyAndVisible];return YES; }

*************存儲(chǔ)賬號(hào)的信息HWAccountTool.m

// 賬號(hào)的存儲(chǔ)路徑 #define HWAccountPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.archive"]#import "HWAccountTool.h" #import "HWAccount.h"@implementation HWAccountTool/*** 存儲(chǔ)賬號(hào)信息** @param account 賬號(hào)模型*/ + (void)saveAccount:(HWAccount *)account {// 獲得賬號(hào)存儲(chǔ)的時(shí)間(accessToken的產(chǎn)生時(shí)間)account.created_time = [NSDate date];// 自定義對(duì)象的存儲(chǔ)必須用NSKeyedArchiver,不再有什么writeToFile方法 [NSKeyedArchiver archiveRootObject:account toFile:HWAccountPath]; }/*** 返回賬號(hào)信息** @return 賬號(hào)模型(如果賬號(hào)過(guò)期,返回nil)*/ + (HWAccount *)account {// 加載模型HWAccount *account = [NSKeyedUnarchiver unarchiveObjectWithFile:HWAccountPath];/* 驗(yàn)證賬號(hào)是否過(guò)期 */// 過(guò)期的秒數(shù)long long expires_in = [account.expires_in longLongValue];// 獲得過(guò)期時(shí)間NSDate *expiresTime = [account.created_time dateByAddingTimeInterval:expires_in];// 獲得當(dāng)前時(shí)間NSDate *now = [NSDate date];// 如果expiresTime <= now,過(guò)期/**NSOrderedAscending = -1L, 升序,右邊 > 左邊NSOrderedSame, 一樣NSOrderedDescending 降序,右邊 < 左邊*/NSComparisonResult result = [expiresTime compare:now];if (result != NSOrderedDescending) { // 過(guò)期return nil;}return account; } @end

*******HWAccount.m

#import "HWAccount.h"@implementation HWAccount + (instancetype)accountWithDict:(NSDictionary *)dict {HWAccount *account = [[self alloc] init];account.access_token = dict[@"access_token"];account.uid = dict[@"uid"];account.expires_in = dict[@"expires_in"];return account; }/*** 當(dāng)一個(gè)對(duì)象要?dú)w檔進(jìn)沙盒中時(shí),就會(huì)調(diào)用這個(gè)方法* 目的:在這個(gè)方法中說(shuō)明這個(gè)對(duì)象的哪些屬性要存進(jìn)沙盒*/ - (void)encodeWithCoder:(NSCoder *)encoder {[encoder encodeObject:self.access_token forKey:@"access_token"];[encoder encodeObject:self.expires_in forKey:@"expires_in"];[encoder encodeObject:self.uid forKey:@"uid"];[encoder encodeObject:self.created_time forKey:@"created_time"]; }/*** 當(dāng)從沙盒中解檔一個(gè)對(duì)象時(shí)(從沙盒中加載一個(gè)對(duì)象時(shí)),就會(huì)調(diào)用這個(gè)方法* 目的:在這個(gè)方法中說(shuō)明沙盒中的屬性該怎么解析(需要取出哪些屬性)*/ - (id)initWithCoder:(NSCoder *)decoder {if (self = [super init]) {self.access_token = [decoder decodeObjectForKey:@"access_token"];self.expires_in = [decoder decodeObjectForKey:@"expires_in"];self.uid = [decoder decodeObjectForKey:@"uid"];self.created_time = [decoder decodeObjectForKey:@"created_time"];}return self; } @end

*********HWAccount.h

#import <Foundation/Foundation.h>@interface HWAccount : NSObject <NSCoding> /** string 用于調(diào)用access_token,接口獲取授權(quán)后的access token。*/ @property (nonatomic, copy) NSString *access_token;/** string access_token的生命周期,單位是秒數(shù)。*/ @property (nonatomic, copy) NSNumber *expires_in;/** string 當(dāng)前授權(quán)用戶的UID。*/ @property (nonatomic, copy) NSString *uid;/** access token的創(chuàng)建時(shí)間 */ @property (nonatomic, strong) NSDate *created_time;+ (instancetype)accountWithDict:(NSDictionary *)dict; @end

?**********HWOAuthViewController.m

#import "HWOAuthViewController.h" #import "AFNetworking.h" #import "HWAccount.h" #import "HWAccountTool.h" #import "MBProgressHUD+MJ.h"@interface HWOAuthViewController () <UIWebViewDelegate>@end@implementation HWOAuthViewController- (void)viewDidLoad {[super viewDidLoad];// 1.創(chuàng)建一個(gè)webViewUIWebView *webView = [[UIWebView alloc] init];webView.frame = self.view.bounds;webView.delegate = self;[self.view addSubview:webView];// 2.用webView加載登錄頁(yè)面(新浪提供的)// 請(qǐng)求地址:https://api.weibo.com/oauth2/authorize/* 請(qǐng)求參數(shù):client_id true string 申請(qǐng)應(yīng)用時(shí)分配的AppKey。redirect_uri true string 授權(quán)回調(diào)地址,站外應(yīng)用需與設(shè)置的回調(diào)地址一致,站內(nèi)應(yīng)用需填寫canvas page的地址。*/NSURL *url = [NSURL URLWithString:@"https://api.weibo.com/oauth2/authorize?client_id=3235932662&redirect_uri=http://www.baidu.com"];NSURLRequest *request = [NSURLRequest requestWithURL:url];[webView loadRequest:request]; }#pragma mark - webView代理方法 - (void)webViewDidFinishLoad:(UIWebView *)webView {[MBProgressHUD hideHUD]; }- (void)webViewDidStartLoad:(UIWebView *)webView {[MBProgressHUD showMessage:@"正在加載..."]; }- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {[MBProgressHUD hideHUD]; }- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {// 1.獲得urlNSString *url = request.URL.absoluteString;// 2.判斷是否為回調(diào)地址NSRange range = [url rangeOfString:@"code="];if (range.length != 0) { // 是回調(diào)地址// 截取code=后面的參數(shù)值int fromIndex = range.location + range.length;NSString *code = [url substringFromIndex:fromIndex];// 利用code換取一個(gè)accessToken [self accessTokenWithCode:code];// 禁止加載回調(diào)地址return NO;}return YES; }/*** 利用code(授權(quán)成功后的request token)換取一個(gè)accessToken** @param code 授權(quán)成功后的request token*/ - (void)accessTokenWithCode:(NSString *)code { /*URL:https://api.weibo.com/oauth2/access_token請(qǐng)求參數(shù):client_id:申請(qǐng)應(yīng)用時(shí)分配的AppKeyclient_secret:申請(qǐng)應(yīng)用時(shí)分配的AppSecretgrant_type:使用authorization_coderedirect_uri:授權(quán)成功后的回調(diào)地址code:授權(quán)成功后返回的code*/// 1.請(qǐng)求管理者AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager]; // mgr.responseSerializer = [AFJSONResponseSerializer serializer];// AFN的AFJSONResponseSerializer默認(rèn)不接受text/plain這種類型// 2.拼接請(qǐng)求參數(shù)NSMutableDictionary *params = [NSMutableDictionary dictionary];params[@"client_id"] = @"3235932662";params[@"client_secret"] = @"227141af66d895d0dd8baca62f73b700";params[@"grant_type"] = @"authorization_code";params[@"redirect_uri"] = @"http://www.baidu.com";params[@"code"] = code;// 3.發(fā)送請(qǐng)求[mgr POST:@"https://api.weibo.com/oauth2/access_token" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {[MBProgressHUD hideHUD];// 將返回的賬號(hào)字典數(shù)據(jù) --> 模型,存進(jìn)沙盒HWAccount *account = [HWAccount accountWithDict:responseObject];// 存儲(chǔ)賬號(hào)信息 [HWAccountTool saveAccount:account];// 切換窗口的根控制器UIWindow *window = [UIApplication sharedApplication].keyWindow;[window switchRootViewController];// UIWindow的分類、HWWindowTool// UIViewController的分類、HWControllerTool} failure:^(AFHTTPRequestOperation *operation, NSError *error) {[MBProgressHUD hideHUD];HWLog(@"請(qǐng)求失敗-%@", error);}]; } @end

UIWindow+Extension.m

#import "UIWindow+Extension.h" #import "HWTabBarViewController.h" #import "HWNewfeatureViewController.h"@implementation UIWindow (Extension) - (void)switchRootViewController {NSString *key = @"CFBundleVersion";// 上一次的使用版本(存儲(chǔ)在沙盒中的版本號(hào))NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:key];// 當(dāng)前軟件的版本號(hào)(從Info.plist中獲得)NSString *currentVersion = [NSBundle mainBundle].infoDictionary[key];if ([currentVersion isEqualToString:lastVersion]) { // 版本號(hào)相同:這次打開和上次打開的是同一個(gè)版本self.rootViewController = [[HWTabBarViewController alloc] init];} else { // 這次打開的版本和上一次不一樣,顯示新特性self.rootViewController = [[HWNewfeatureViewController alloc] init];// 將當(dāng)前的版本號(hào)存進(jìn)沙盒 [[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:key];[[NSUserDefaults standardUserDefaults] synchronize];} } @end

?************HWHomeViewController.m

#import "HWHomeViewController.h" #import "HWDropdownMenu.h" #import "HWTitleMenuViewController.h" #import "AFNetworking.h" #import "HWAccountTool.h" #import "HWTitleButton.h" #import "UIImageView+WebCache.h" #import "HWUser.h" #import "HWStatus.h" #import "MJExtension.h" // 第三方的框架@interface HWHomeViewController () <HWDropdownMenuDelegate> /*** 微博數(shù)組(里面放的都是HWStatus模型,一個(gè)HWStatus對(duì)象就代表一條微博)*/ @property (nonatomic, strong) NSMutableArray *statuses; @end@implementation HWHomeViewController- (NSMutableArray *)statuses {if (!_statuses) {self.statuses = [NSMutableArray array];}return _statuses; }- (void)viewDidLoad {[super viewDidLoad];// 設(shè)置導(dǎo)航欄內(nèi)容 [self setupNav];// 獲得用戶信息(昵稱) [self setupUserInfo];// 集成刷新控件 [self setupRefresh]; }/*** 3. 集成刷新控件*/ - (void)setupRefresh {UIRefreshControl *control = [[UIRefreshControl alloc] init];[control addTarget:self action:@selector(refreshStateChange:) forControlEvents:UIControlEventValueChanged];[self.tableView addSubview:control]; }/*** 3-1 UIRefreshControl進(jìn)入刷新狀態(tài):加載最新的數(shù)據(jù)*/ - (void)refreshStateChange:(UIRefreshControl *)control {// 1.請(qǐng)求管理者AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];// 2.拼接請(qǐng)求參數(shù)HWAccount *account = [HWAccountTool account];NSMutableDictionary *params = [NSMutableDictionary dictionary];params[@"access_token"] = account.access_token;// 取出最前面的微博(最新的微博,ID最大的微博)HWStatus *firstStatus = [self.statuses firstObject];if (firstStatus) {// 若指定此參數(shù),則返回ID比since_id大的微博(即比since_id時(shí)間晚的微博),默認(rèn)為0params[@"since_id"] = firstStatus.idstr;}// 3.發(fā)送請(qǐng)求[mgr GET:@"https://api.weibo.com/2/statuses/friends_timeline.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {// 將 "微博字典"數(shù)組 轉(zhuǎn)為 "微博模型"數(shù)組NSArray *newStatuses = [HWStatus objectArrayWithKeyValuesArray:responseObject[@"statuses"]]; //第三方的框架// 將最新的微博數(shù)據(jù),添加到總數(shù)組的最前面NSRange range = NSMakeRange(0, newStatuses.count);NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:range];[self.statuses insertObjects:newStatuses atIndexes:set];// 刷新表格 [self.tableView reloadData];// 結(jié)束刷新刷新 [control endRefreshing];} failure:^(AFHTTPRequestOperation *operation, NSError *error) {HWLog(@"請(qǐng)求失敗-%@", error);// 結(jié)束刷新刷新 [control endRefreshing];}]; }/*** 2. 獲得用戶信息(昵稱)*/ - (void)setupUserInfo {// 1.請(qǐng)求管理者AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];// 2.拼接請(qǐng)求參數(shù)HWAccount *account = [HWAccountTool account];NSMutableDictionary *params = [NSMutableDictionary dictionary];params[@"access_token"] = account.access_token;params[@"uid"] = account.uid;// 3.發(fā)送請(qǐng)求[mgr GET:@"https://api.weibo.com/2/users/show.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {// 標(biāo)題按鈕UIButton *titleButton = (UIButton *)self.navigationItem.titleView;// 設(shè)置名字HWUser *user = [HWUser objectWithKeyValues:responseObject];[titleButton setTitle:user.name forState:UIControlStateNormal];// 存儲(chǔ)昵稱到沙盒中account.name = user.name;[HWAccountTool saveAccount:account];} failure:^(AFHTTPRequestOperation *operation, NSError *error) {HWLog(@"請(qǐng)求失敗-%@", error);}]; }/*** 1. 設(shè)置導(dǎo)航欄內(nèi)容*/ - (void)setupNav {/* 設(shè)置導(dǎo)航欄上面的內(nèi)容 */self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(friendSearch) image:@"navigationbar_friendsearch" highImage:@"navigationbar_friendsearch_highlighted"];self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(pop) image:@"navigationbar_pop" highImage:@"navigationbar_pop_highlighted"];/* 中間的標(biāo)題按鈕 */HWTitleButton *titleButton = [[HWTitleButton alloc] init];// 設(shè)置圖片和文字NSString *name = [HWAccountTool account].name;[titleButton setTitle:name?name:@"首頁(yè)" forState:UIControlStateNormal];// 監(jiān)聽標(biāo)題點(diǎn)擊 [titleButton addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside];self.navigationItem.titleView = titleButton; }/*** 1-1 標(biāo)題點(diǎn)擊*/ - (void)titleClick:(UIButton *)titleButton {// 1.創(chuàng)建下拉菜單HWDropdownMenu *menu = [HWDropdownMenu menu];menu.delegate = self;// 2.設(shè)置內(nèi)容HWTitleMenuViewController *vc = [[HWTitleMenuViewController alloc] init];vc.view.height = 150;vc.view.width = 150;menu.contentController = vc;// 3.顯示 [menu showFrom:titleButton]; }- (void)friendSearch {NSLog(@"friendSearch"); }- (void)pop {NSLog(@"pop"); }#pragma mark - HWDropdownMenuDelegate /*** 下拉菜單被銷毀了*/ - (void)dropdownMenuDidDismiss:(HWDropdownMenu *)menu {UIButton *titleButton = (UIButton *)self.navigationItem.titleView;// 讓箭頭向下titleButton.selected = NO; }/*** 下拉菜單顯示了*/ - (void)dropdownMenuDidShow:(HWDropdownMenu *)menu {UIButton *titleButton = (UIButton *)self.navigationItem.titleView;// 讓箭頭向上titleButton.selected = YES; }#pragma mark - Table view data source - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return self.statuses.count; }- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {static NSString *ID = @"status";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];if (!cell) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];}// 取出這行對(duì)應(yīng)的微博字典HWStatus *status = self.statuses[indexPath.row];// 取出這條微博的作者(用戶)HWUser *user = status.user;cell.textLabel.text = user.name;// 設(shè)置微博的文字cell.detailTextLabel.text = status.text;// 設(shè)置頭像UIImage *placehoder = [UIImage imageNamed:@"avatar_default_small"];[cell.imageView sd_setImageWithURL:[NSURL URLWithString:user.profile_image_url] placeholderImage:placehoder];return cell; }/**1.將字典轉(zhuǎn)為模型2.能夠下拉刷新最新的微博數(shù)據(jù)3.能夠上拉加載更多的微博數(shù)據(jù)*/ @end

?***HWTitleButton.h

#import "HWTitleButton.h"@implementation HWTitleButton- (id)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {[self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];self.titleLabel.font = [UIFont boldSystemFontOfSize:17];[self setImage:[UIImage imageNamed:@"navigationbar_arrow_down"] forState:UIControlStateNormal];[self setImage:[UIImage imageNamed:@"navigationbar_arrow_up"] forState:UIControlStateSelected];}return self; }- (void)layoutSubviews {[super layoutSubviews];// 如果僅僅是調(diào)整按鈕內(nèi)部titleLabel和imageView的位置,那么在layoutSubviews中單獨(dú)設(shè)置位置即可// 1.計(jì)算titleLabel的frameself.titleLabel.x = self.imageView.x;// 2.計(jì)算imageView的frameself.imageView.x = CGRectGetMaxX(self.titleLabel.frame); }- (void)setTitle:(NSString *)title forState:(UIControlState)state {[super setTitle:title forState:state];// 只要修改了文字,就讓按鈕重新計(jì)算自己的尺寸 [self sizeToFit]; }- (void)setImage:(UIImage *)image forState:(UIControlState)state {[super setImage:image forState:state];// 只要修改了圖片,就讓按鈕重新計(jì)算自己的尺寸 [self sizeToFit]; } @end #import <UIKit/UIKit.h>@interface HWTitleButton : UIButton@end

??HWStatus.h

#import <Foundation/Foundation.h> @class HWUser;@interface HWStatus : NSObject /** string 字符串型的微博ID*/ @property (nonatomic, copy) NSString *idstr;/** string 微博信息內(nèi)容*/ @property (nonatomic, copy) NSString *text;/** object 微博作者的用戶信息字段 詳細(xì)*/ @property (nonatomic, strong) HWUser *user; @end

?HWStatus.m

#import "HWStatus.h"@implementation HWStatus @end

?

轉(zhuǎn)載于:https://www.cnblogs.com/ios-g/p/4828212.html

總結(jié)

以上是生活随笔為你收集整理的IOS第四天-新浪微博 -存储优化OAuth授权账号信息,下拉刷新,字典转模型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。