iOS开发 关于处理网络请求返回的数据

来源:http://www.sh-fengwen.com 作者:鲜果干果 人气:152 发布时间:2019-09-11
摘要:这里总结的是cell请求和返回数据许多细节方面的处理项目地址: int 强制类型转换 int i = (int)[dic objectForKey @"code"] 打印i值,出现和JSON返回的值不一样的情况,正确的做法则是 int status

这里总结的是cell请求和返回数据许多细节方面的处理项目地址:

int 强制类型转换

int i = (int)[dic objectForKey @"code"]打印i值,出现和JSON返回的值不一样的情况,正确的做法则是int status = [[dic objectForKey:@"status"] intValue],还可以把获取到的i值,进行类型判断[i isKindOfClass [NSNumber class]]后,再进行处理[number intvalue]

    • 一般当系统不能满足我们的需求时,就要自定义
    • 发现cell固定,大小相同的时候勾选Xib,今后的cell从Xib中加载
    • cell一般要到缓存池中取,缓存池中没有就注册,重新创建
      • 注册时Xib中要设置Identifier为:tag
        • 勾选Xib的时候用registerNib
        • 没有的时候用registerClass
      • Xib是固定的,可以设置一个高度为70
  • 有关于cell之间的分割线的设置

  • 系统的满足不了我们了要求太粗,我们需要自定义分割线,一般有两种方法
  • 首先设置cell的的高,去掉系统自带的分割线
- viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"推荐标签"; self.view.backgroundColor = CYCommonBgColor; // 设置行高 self.tableView.rowHeight = 70; // 去掉系统自带的分割线 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; }
  • 然后再考虑怎么设置分割线
  • 方法一:添加一个UIView(设置它的frame:距左,右,下为0 。设定高为1,透明度为0.2)
    • 但是这种方法带来了许多的子控件,当我们的cell较多的时候不推荐这种方法
  • 方法二:保持cell的位置不变,高度都减1
    • 这样就可以少许多的子控件
    • 但是这样又有一些细节和注意的地方。分析如下:
  • 有人会想在下面的cellForRowAtIndexPath:方法中修改cell的frame
    • 但是这是不可能的。因为这里是返回indexPath位置对应的cell,你如果是在这里修改后,一旦return cell。
    • 又会被TableView重新计算IndexPath对应cell的高度(前面你有有设定cell高度为70),frame等
    • 循环利用,又会被系统修改回去
    • 所以别想着在这里修改cell的frame
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ CYTagCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tag"]; return cell;}
  • 也有人可能会想着实现代理方法,在下面的didSelectRowAtIndexPath:方法中修改cell的高度,每选中一次就让它的高度减1也可以实现分割线
    • 但是:同样的在上面的cellForRowAtIndexPath:方法中,用户一做上拉操作,就会循环利用,cell的高又会被系统重新修改回去
- tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ CYTagCell *cell = (CYTagCell *)[tableView cellForRowAtIndexPath:indexPath]; cell.height -= 1;}
  • 所以存在的问题:自己手动修改了cell的frame后,很有可能会被系统改回去
  • 那么解决的方案:在系统设置完cell的frame后,自己再手动修改cell的frame, 重写setFrame:方法
    • 重写这个方法的目的:拦截cell的frame设置,系统改完后,我再改,永远改在系统的后面
    • 不用担心高度会递减,前面有设置cell的高度为70,在每次传进cell高度减1前,cell都会重新设置高度为原来的70
- setFrame:frame{ frame.size.height -= 1; [super setFrame:frame];}
  • 重写setFrame:方法引申出来的价值
  • 1.当我们今后要拦截系统的某些设置(frame,size等),某些操作的时候。我们就要想到是不是可以去重写它们相应的方法
  • 2.今后如果我们自定义的控件有一些特殊的需求,不希望外界可以轻松修改我们内部的值(像frame,size等)。或者是为了避免外界误传值修改了尺寸等值,我们就可以重写setFrame:方法
    • 当然别也可以通过修改bounds来修改尺寸,你就还得重写setBounds:方法,人家也还可以通过修改transform来修改,你就还得重写setTransform:方法。一般不会如此变态
    • 只是说记得有这么个细节和问题,知道可以这么干
    • 设置左右间距
      • x向右移动一个你定的间距margin,然后width减2倍间距margin
      • 就设置好了cell的分割线,以及左右间隔或者是左右间隔线
- setFrame:frame{ frame.size.height -= 1; frame.origin.x = 5; frame.size.width -= 2 * frame.origin.x; [super setFrame:frame];}
  • 网络请求真实的数据
  • 首先,要注意的地方:
    • 使用Xcode7进行数据请求时
    • 苹果新特性要求App内访问网络请求,要采用 HTTPS 协议
    • 但是现在公司的项目使用的是 HTTP 协议,使用私有加密方式保证数据安全。现在也不能马上改成 HTTPS 协议传输。
      • 解决办法:
        • 在Info.plist中添加 NSAppTransportSecurity 类型 Dictionary
        • 在 NSAppTransportSecurity 下添加 NSAllowsArbitraryLoads 类型Boolean ,值设为 YES
          • 方式一: 使用文本编辑Info.plist, 在当中添加:
<key>NSAppTransportSecurity</key><dict> <key>NSAllowsArbitraryLoads</key> <true/></dict>
  • 方式二: 在Info.plist中添加:

图片 1

  • 发送请求给服务器,获取数据
    • 加载标签数据
  • 使用AFNetworking框架
    • 先要根据API文档请求参数
    • 参数是一个字典,里面有各种参数
  • 发送请求
 // 加载标签数据 // 请求参数 NSMutableDictionary *params = [NSMutableDictionary dictionary]; params[@"a"] = @"tag_recommend"; params[@"action"] = @"sub"; params[@"c"] = @"topic"; // 发送请求 [[AFHTTPSessionManager manager] GET:@"http://api.budejie.com/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) { // 将服务器的数据写成plist。方便查看数据结构 [responseObject writeToFile:@"/Users/gecongying/Desktop/tag.plist" atomically:YES]; } failure:^(NSURLSessionDataTask *task, NSError *error) { }];}
  • 一般开发的适合你可以将服务器的数据写成plist。这样方便查看数据结构

图片 2

  • 可以看出plist文件中有许多的字典数组,所以我们要将字典转模型

  • 字典转模型时,公司的服务器可能传回来一堆的数组,但是真正用到可以用于显示的数据只有几个,没必要每个都写,只取我需要的

    • 像这里只需要用到“头像”“订阅数”“name”三个数据
  • 字典数组转模型数组。所以搞一个模型数组(新建标签模型CYTag),这里选用MJExtension框架

  • 在CYTag.h文件中

#import <Foundation/Foundation.h>@interface CYTag : NSObject/** 图片 */@property (nonatomic, copy) NSString *image_list;/** 订阅数 */@property (nonatomic, assign) NSInteger sub_number;// 这里用NSInteger是为了后面更好的处理数字/** 名字 */@property (nonatomic, copy) NSString *theme_name;@end
  • 在CYTagViewController.m文件中
  • 用一个标签数组保存标签数据(里面放的是CYTag模型)
#import "CYTagViewController.h"#import "CYTagCell.h"#import <AFNetworking.h>#import <MJExtension.h>#import "CYTag.h"@interface CYTagViewController ()/** 所有的标签数据(里面存放的都是CYTag模型) */@property (nonatomic, strong) NSArray *tags;@end@implementation CYTagViewController
  • 在TableView数据源方法中,cell返回的个数
#pragma mark - <UITableViewDataSource>- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.tags.count;}
  • 在CYTagCell.Xib文件中,将cell中的控件以及控件之间的束设置好。

图片 3

  • 要把模型数组显示到cell对应的位置,所以得进行拖线,拖到CYTagcell.m文件中
@interface CYTagCell()@property (weak, nonatomic) IBOutlet UIImageView *imageListView;@property (weak, nonatomic) IBOutlet UILabel *themeNameLabel;@property (weak, nonatomic) IBOutlet UILabel *subNumberLabel;@end
  • 字典转模型
  • 字典转模型后要记得刷新表格
 // 发送请求 [[AFHTTPSessionManager manager] GET:@"http://api.budejie.com/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) { // 将服务器的数据写成plist。方便查看数据结构 // [responseObject writeToFile:@"/Users/gecongying/Desktop/tag.plist" atomically:YES]; // responseObject:字典数组 // self.tags:模型数组 // responseObject -> self.tags // 字典数组转模型数组 self.tags = [CYTag objectArrayWithKeyValuesArray:responseObject]; // 刷新表格 [self.tableView reloadData]; } failure:^(NSURLSessionDataTask *task, NSError *error) { }];}

图片 4

  • CYTagCell内部要拿到相应的数据,所以也需要有标签模型
    • 下面的命名之所以用tagModel而不用tag
    • 因为系统控件基本都有tag属性,取名不正确会被系统覆盖
    • 所以有时候取名也得注意
@classCYTag;@interface CYTagCell : UITableViewCell/** 标签模型 */@property (nonatomic, strong) CYTag *tagModel;

本文由美高梅游戏平台网站发布于鲜果干果,转载请注明出处:iOS开发 关于处理网络请求返回的数据

关键词:

上一篇:GitHub正确打开方式-协同项目

下一篇:没有了

最火资讯