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;
}

浅谈Charles —— 青花瓷的更多相关文章

  1. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  2. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  3. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  4. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  5. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  6. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  7. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  8. Linux特殊符号浅谈

    Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...

  9. 浅谈Angular的 $q, defer, promise

    浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00  博客园-原创精华区 原文  http://www.cnblogs.com/big-snow/ ...

随机推荐

  1. 设计模式实战系列之@Builder和建造者模式

    前言 备受争议的Lombok,有的人喜欢它让代码更整洁,有的人不喜欢它,巴拉巴拉一堆原因.在我看来Lombok唯一的缺点可能就是需要安装插件了,但是对于业务开发的项目来说,它的优点远远超过缺点. 我们 ...

  2. Ubuntu无法安装 英伟达显卡

    安装Ubuntu无法正常驱动英伟达,这时需要在启动参数中添加nomodset 如果不会添加参数可以参考这篇文章:安装ubuntu时黑屏三种解决办法

  3. 使用Spring Boot开发者工具进行自动重启和页面自动刷新

    简介 大家可能都听说过开发Node.js应用时可以使用多种工具对开发者提供便利,如WebPack提供了开发者服务器来支持js应用动态更替,并在保存文件时自动刷新浏览器.Spring Boot也提供了相 ...

  4. Golang gRPC学习(04): Deadlines超时限制

    为什么要使用Deadlines 当我们使用gRPC时,gRPC库关系的是连接,序列化,反序列化和超时执行.Deadlines 允许gRPC客户端设置自己等待多长时间来完成rpc操作,直到出现这个错误 ...

  5. 【HDU3038】How Many Answers Are Wrong - 带权并查集

    描述 TT and FF are ... friends. Uh... very very good friends -________-b FF is a bad boy, he is always ...

  6. Java 泛型(参数化类型)

    Java 泛型 Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所 ...

  7. 第5章 JDBC/ODBC服务器

    第5章 JDBC/ODBC服务器 Spark SQL也提供JDBC连接支持,这对于让商业智能(BI)工具连接到Spark集群上以 及在多用户间共享一个集群的场景都非常有用.JDBC 服务器作为一个独立 ...

  8. 为什么我们需要Logstash,Fluentd等日志摄取器?

    前文传送门:Logging with ElasticSearch, Kibana, ASP.NET Core and Docker 疑问:既然应用能直接向ElasticSearch写日志,为什么我们还 ...

  9. [PyTorch 学习笔记] 3.1 模型创建步骤与 nn.Module

    本章代码:https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson3/module_containers.py 这篇文章来看下 ...

  10. Linux环境编程进程间通信机制理解

    一.Linux系统调用主要函数 二.创建进程 1.创建子进程系统调用fork() 2.验证fork()创建子进程效果 3.系统调用fork()与挂起系统调用wait() 三.模拟进程管道通信 四.pi ...