• 浅谈Charles —— 青花瓷


    Charles —— 青花瓷

    • 网络抓包工具
    • 可以拦截 iPhone/Android 手机中 App 的非加密网络请求数据

    使用

    • 手机&电脑在同一个局域网
    • 确保电脑能够通过路由器访问互联网
    • 电脑安装 Charles
    • 启动 Charles,禁用 MAC OS X Proxy & Mozilla FireFox Proxy
    • 设置手机的网络代理
      • ip: 电脑的 ip
      • 端口: 8888

    注意,如果让电脑通过手机的 3G 访问网络,无法拦截数据

    拦截网易新闻数据

    分类 URL
    新闻首页 http://c.m.163.com/nc/article/headline/T1348647853363/0-20.html
    科技 http://c.m.163.com/nc/article/list/T1348649580692/0-20.html
    手机 http://c.m.163.com/nc/article/list/T1348649654285/0-20.html
    移动互联 http://c.m.163.com/nc/article/list/T1351233117091/0-20.html
    首页广告 http://c.m.163.com/nc/ad/headline/0-4.html

    网络访问

    建立网络访问单例

    + (instancetype)sharedManager {
        static NetworkTools *instance;
    
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
    
            // 注意:baseURL 应该以 / 结尾
            NSURL *baseURL = [NSURL URLWithString:@"http://c.m.163.com/nc/article/headline/"];
            NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    
            instance = [[self alloc] initWithBaseURL:baseURL sessionConfiguration:config];
    
        return instance;
    }
    

    加载新闻首页数据

    - (void)loadData {
        [[NetworkTools sharedManager] GET:@"T1348647853363/0-20.html" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
    
            NSLog(@"%@ %@", responseObject, [responseObject class]);
    
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@"%@", error);
        }];
    }
    

    运行测试,statecode == 200,但是不支持数据格式 "text/html"

    扩展反序列化格式类型

    • NetworkTools 单例中,扩展反序列化格式类型
    instance.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
    

    字典转模型

    字典使用技巧 - 取第一个键值内容

    // 直接取出字典中第一个 key T1348647853363 对应的数组
    NSArray *array = responseObject[responseObject.keyEnumerator.nextObject];
    NSLog(@"%@", array);
    

    新闻模型

    .h

    ///  标题
    @property (nonatomic, copy) NSString *title;
    ///  摘要
    @property (nonatomic, copy) NSString *digest;
    ///  配图地址
    @property (nonatomic, copy) NSString *imgsrc;
    
    + (instancetype)newsWithDict:(NSDictionary *)dict;
    

    .m

    + (instancetype)newsWithDict:(NSDictionary *)dict {
        id obj = [[self alloc] init];
    
        [obj setValuesForKeysWithDictionary:dict];
    
        return obj;
    }
    

    字典转模型

    NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:array.count];
    
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        [arrayM addObject:[News newsWithDict:obj]];
    }];
    
    NSLog(@"%@", arrayM);
    

    运行测试-崩溃

    • 因为网络字典中的属性键值比 News 模型中的属性多,直接使用 setValuesForKeysWithDictionary 方法会崩溃

    修改新闻模型

    + (instancetype)newsWithDict:(NSDictionary *)dict {
        id obj = [[self alloc] init];
    
        NSArray *properties = [self properties];
        for (NSString *key in properties) {
            if (dict[key] != nil) {
                [obj setValue:dict[key] forKey:key];
            }
        }
    
        return obj;
    }
    
    + (NSArray *)properties {
        return @[@"title", @"digest", @"imgsrc"];
    }
    

    增加 description

    - (NSString *)description {
        NSDictionary *dict = [self dictionaryWithValuesForKeys:[News properties]];
    
        return [NSString stringWithFormat:@"<%@: %p> %@", self.class, self, dict];
    }
    

    利用运行时动态获取类属性

    const char* propertiesKey = "propertiesKey";
    
    + (NSArray *)properties {
        NSMutableArray *arrayM = objc_getAssociatedObject(self, propertiesKey);
        if (arrayM != nil) {
            NSLog(@"返回关联数组");
            return arrayM;
        }
    
        NSLog(@"动态获取类属性");
    
        unsigned int count = 0;
        objc_property_t *ptys = class_copyPropertyList([self class], &count);
    
        arrayM = [NSMutableArray arrayWithCapacity:count];
        for (unsigned int i = 0; i < count; ++i) {
            objc_property_t pty = ptys[i];
            const char* cname = property_getName(pty);
            [arrayM addObject:[NSString stringWithUTF8String:cname]];
        }
    
        free(ptys);
    
        objc_setAssociatedObject(self, propertiesKey, arrayM, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
        return arrayM;
    }
    
  • 相关阅读:
    C#高级编程第11版
    做点字符串题
    Codeforces Round #681 (Div. 1, based on VK Cup 2019-2020
    Educational Codeforces Round 97 题解
    AtCoder Regular Contest 106 题解
    Kick Start Round G 2020 题解
    CCSP 2020题解
    Codeforces Round #675 (Div. 2) 题解
    AtCoder Regular Contest 104
    Kick Start Round F 2020 题解
  • 原文地址:https://www.cnblogs.com/jiahao89/p/5118309.html
Copyright © 2020-2023  润新知