AFNetworking粗解

111181.png

框架GitHub地址AFNetworking

构造:

NSURLSession

  • AFURLSessionManager
  • AFHTTPSessionManager

序列化

  • <AFURLRequestSerialization>
    • AFHTTPRequestSerializer
    • AFJSONRequestSerializer
    • AFPropertyListRequestSerializer
  • <AFURLResponseSerialization>
    • AFHTTPResponseSerializer
    • AFJSONResponseSerializer
    • AFXMLParserResponseSerializer
    • AFXMLDocumentResponseSerializer (Mac OS X)
    • AFPropertyListResponseSerializer
    • AFImageResponseSerializer
    • AFCompoundResponseSerializer

额外的功能

  • AFSecurityPolicy
  • AFNetworkReachabilityManager

使用

AFURLSessionManager

AFURLSessionManager创建和管理一个NSURLSession
基于指定的对象nsurlsessionconfiguration对象,符合
<NSURLSessionTaskDelegate>,<NSURLSessionDataDelegate>,<NSURLSessionDownloadDelegate>,和<NSURLSessionDelegate>

创建一个下载任务
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {

NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory
inDomain:NSUserDomainMask appropriateForURL:nil 
create:NO error:nil]; 

return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];

} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) 
{ 

NSLog(@"File downloaded to: %@", filePath);
}];

[downloadTask resume];
创建一个上传的任务
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];

NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request 
fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { if (error) { 

NSLog(@"Error: %@", error); 
} else 

{ NSLog(@"Success: %@ %@", response, responseObject); 
}}];

[uploadTask resume];

创建一个多部分请求上传任务,进步

NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" 
URLString:@"http://example.com/upload" parameters:nil 
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { 

[formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] 
name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil]; 

} error:nil];

AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

NSURLSessionUploadTask *uploadTask;

uploadTask = [manager uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) { 

// This is not called back on the main queue. 
// You are responsible for dispatching to the main queue for UI 

updates dispatch_async(dispatch_get_main_queue(), ^{ 

//Update the progress view [progressView setProgress:uploadProgress.fractionCompleted];

}); } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { 
if (error) { 

NSLog(@"Error: %@", error);
 } else
{

NSLog(@"%@ %@", response, responseObject); 
} }];

[uploadTask resume];

创建一个数据任务

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

NSURL *URL = [NSURL URLWithString:@"http://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { if (error) { NSLog(@"Error: %@", error); 
} else
 { 
NSLog(@"%@ %@", response, responseObject); 
}}];

[dataTask resume];

请求序列化
请求的URL字符串序列化程序创建请求,编码参数作为查询字符串或HTTP体。

NSString *URLString = @"http://example.com";
NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]};

查询字符串参数编码

[[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" 
URLString:URLString parameters:parameters error:nil];

URL形式参数编码

[[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" 
URLString:URLString parameters:parameters error:nil];

//POST http://example.com/
Content-Type: application/x-www-form-urlencoded
foo=bar&baz[]=1&baz[]=2&baz[]=3

JSON编码参数

POST http://example.com/
Content-Type: application/x-www-form-urlencoded
foo=bar&baz[]=1&baz[]=2&baz[]=3

//POST http://example.com/
Content-Type: application/json

{"foo": "bar", "baz": [1,2,3]}

AFNetworkReachabilityManager

AFNetworkReachabilityManager
 monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces.
Do not use Reachability to determine if the original request should be sent.You should try to send it.

You can use Reachability to determine when a request should be automatically retried.Although it may still fail, a Reachability notification that the connectivity is available is a good time to retry something.

Network reachability is a useful tool for determining why a request might have failed.After a network request has failed, telling the user they're offline is better than giving them a more technical but accurate error, such as "request timed out."

See also [WWDC 2012 session 706, "Networking Best Practices."](https://developer.apple.com/videos/play/wwdc2012-706/).

Shared Network Reachability

[[AFNetworkReachabilityManager sharedManager] 
setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { 

NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status));
}];

[[AFNetworkReachabilityManager sharedManager] 
startMonitoring];

安全政策
afsecuritypolicy评估服务器信任与寄托的X.509证书的公共密钥和安全连接。
在你的应用程序添加SSL证书有助于防止中间人攻击和其他安全漏洞。处理敏感的客户数据或财务信息应用强烈鼓励所有通信路由的配置和启用HTTPS连接SSL钉扎。
使无效的SSL证书

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

manager.securityPolicy.allowInvalidCertificates = YES; 
// not recommended for production

用白话说一次:

AFN
一、什么是AFN
全称是AFNetworking,是对NSURLConnection的一层封装
虽然运行效率没有ASI高,但是使用比ASI简单
在iOS开发中,使用比较广泛

AFN的github地址
https://github.com/pokeb/AFNetworking/AFNetworking

二、AFN结构
NSURLConnection
AFURLConnectionOperation
AFHTTPRequestOperation
AFHTTPRequestOperationManager(封装了常用的 HTTP 方法)
属性
baseURL :AFN建议开发者针对 AFHTTPRequestOperationManager 自定义个一个单例子类,设置 baseURL, 所有的网络访问,都只使用相对路径即可
requestSerializer :请求数据格式/默认是二进制的 HTTP
responseSerializer :响应的数据格式/默认是 JSON 格式
operationQueue
reachabilityManager :网络连接管理器

方法
manager :方便创建管理器的类方法
HTTPRequestOperationWithRequest :在访问服务器时,如果要告诉服务器一些附加信息,都需要在 Request 中设置
GET
POST

NSURLSession
AFURLSessionManager
AFHTTPSessionManager(封装了常用的 HTTP 方法)
GET
POST
UIKit + AFNetworking 分类
NSProgress :利用KVO

半自动的序列化&反序列化的功能
AFURLRequestSerialization :请求的数据格式/默认是二进制的
AFURLResponseSerialization :响应的数据格式/默认是JSON格式

附加功能
安全策略
HTTPS
AFSecurityPolicy

网络检测
对苹果的网络连接检测做了一个封装
AFNetworkReachabilityManager

三、AFN基本使用

1.AFHTTPSessionManager
是AFN中最重要的对象之一
封装了HTTP请求的常见处理
GET\POST请求
解析服务器的响应数据

创建AFHTTPSessionManager
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];`

AFHTTPSessionManager的GET\POST请求
// GET请求
/* http://120.25.226.186:32812/login?username=520it&pwd=520it 
第一个参数: 请求的地址 http://120.25.226.186:32812/login 
第二个参数: 请求的参数 username=520it&pwd=520it 
第三个参数: 请求成功的回调 第四个参数: 请求失败的回调 只要利用AFN发送请求, 如果服务器返回的是JSON数据, 那么AFN会自动将JSON转会成OC对象返回给我们 
*/
- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
// POST请求
- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

代码示例

// GET- (void)get2{
 // 1.创建AFN管理者 
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
// 2.利用AFN管理者发送请求 
NSDictionary *params = @{ @"username" : @"520it", @"pwd" : @"520it" };
 [manager GET:@"http://120.25.226.186:32812/login" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) { 
NSLog(@"请求成功---%@", responseObject); 
} failure:^(NSURLSessionDataTask *task, NSError *error) { 
NSLog(@"请求失败---%@", error);
 }];
}


// POST- (void)post2{ 

// 1.创建AFN管理者 
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
// 2.利用AFN管理者发送请求 
NSDictionary *params = @{ @"username" : @"520it", @"pwd" : @"520it" };

 [manager POST:@"http://120.25.226.186:32812/login" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) { 
NSLog(@"请求成功---%@", responseObject); 
} failure:^(NSURLSessionDataTask *task, NSError *error) { 
NSLog(@"请求失败---%@", error); 
}];
}

2.AFHTTPRequestOperationManager
创建AFHTTPRequestOperationManager

// 1.创建AFN管理者 
// AFHTTPRequestOperationManager内部包装了NSURLConnection AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];


AFHTTPRequestOperationManager的GET\POST请求
// GET
- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

// POST请求
- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

代码示例

- (void)get{ 
// 1.创建AFN管理者 
// AFHTTPRequestOperationManager内部包装了NSURLConnection 
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
// 2.利用AFN管理者发送请求 
NSDictionary *params = @{ @"username" : @"520it", @"pwd" : @"520it" }; 
[manager GET:@"http://120.25.226.186:32812/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { 
NSLog(@"请求成功---%@", responseObject);
 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
NSLog(@"请求失败---%@", error); }];
}
- (void)post{ 
// 1.创建AFN管理者 
// AFHTTPRequestOperationManager内部包装了NSURLConnection 
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 

// 2.利用AFN管理者发送请求
 NSDictionary *params = @{ @"username" : @"520it", @"pwd" : @"520it" }; 
[manager POST:@"http://120.25.226.186:32812/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { 
NSLog(@"请求成功---%@", responseObject);
 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"请求失败---%@", error); 
}];
}

四、AFN文件下载

// 执行下载文件的方法,可以监控下载进度
- (void)downLoadMonitor{ 
// 1.创建网络管理者 
// AFHTTPSessionManager 基于NSURLSession 
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
// 2.利用网络管理者下载数据 
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"]]; 
/* 
destination - targetPath: 系统给我们自动写入的文件路径 - block的返回值, 要求返回一个URL, 返回的这个URL就是剪切的位置的路径 completionHandler - url :destination返回的URL == block的返回的路径 
*/ 

/*
 @property int64_t totalUnitCount; 需要下载文件的总大小 
@property int64_t completedUnitCount; 当前已经下载的大小 
*/ 

NSProgress *progress = nil; 
NSURLSessionDownloadTask *downTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 
NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename]; 
return [NSURL fileURLWithPath:path]; 
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { 
NSLog(@"%@",filePath.absoluteString);
 }]; 

/* 
要跟踪进度,需要使用 NSProgress,是在 iOS 7.0 推出的,专门用来跟踪进度的类! NSProgress只是一个对象!如何跟踪进度!-> KVO 对属性变化的监听! @property int64_t totalUnitCount; 总单位数
@property int64_t completedUnitCount; 完成单位数
*/ 
// 给Progress添加监听 KVO
 [progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil];
 // 3.启动任务 [downTask resume];}
// 收到通知调用的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSProgress *)object change:(NSDictionary *)change context:(void *)context{ NSLog(@"%f",1.0 * object.completedUnitCount / object.totalUnitCount); 
// 回到主队列刷新UI 
dispatch_async(dispatch_get_main_queue(), ^{ self.progress.progress = 1.0 * object.completedUnitCount / object.totalUnitCount; });
}

五、AFN序列化
默认是JSON数据,接收类型是JSON
如果接收的类型和返回的类型不匹配会报错

// 1.创建AFN管理者

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
// 默认请求二进制 
// 默认响应是JSON 
// 告诉AFN,支持接受 text/xml 的数据 
// [AFJSONResponseSerializer serializer].acceptableContentTypes = [NSSet setWithObject:@"text/xml"];
 // 告诉AFN如何解析数据 
// 告诉AFN客户端, 将返回的数据当做JSON来处理,默认的是以JSON处理
// manager.responseSerializer = [AFJSONResponseSerializer serializer]; 
// 告诉AFN客户端, 将返回的数据当做XML来处理
// manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
 // 告诉AFN客户端, 将返回的数据当做而进行来数据 (服务器返回什么就是什么) manager.responseSerializer = [AFHTTPResponseSerializer serializer];

六、AFN文件上传
// formData: 专门用于拼接需要上传的数据

- (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure

AFN上传文件代码示例

// 1.创建网络管理者 
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
// 2.利用网络管理者上传数据 NSDictionary *dict = @{@"username":@"Syl"}; 
// formData: 专门用于拼接需要上传的数据
 [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock: ^void(id<AFMultipartFormData> formData) { 
/*
 Data: 需要上传的数据 
name: 服务器参数的名称 
fileName: 文件名称 
mimeType: 文件的类型 
*/ 
UIImage *image =[UIImage imageNamed:@"minion_02"]; 
NSData *data = UIImagePNGRepresentation(image); [formData appendPartWithFileData:data name:@"file" fileName:@"abc.png" mimeType:@"image/png"]; 
/* NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/CertificateSigningRequest.certSigningRequest"]; 
// 任意的二进制数据
MIMEType application/octet-stream 
// [formData appendPartWithFileURL:url name:@"file" fileName:@"abc.cer" mimeType:@"application/octet-stream" error:nil]; [formData appendPartWithFileURL:url name:@"file" error:nil]; 
*/ 
} success:^void(NSURLSessionDataTask * task, id responseObject) { 
// 请求成功 NSLog(@"请求成功 %@", responseObject); 
} failure:^void(NSURLSessionDataTask * task, NSError * error) 
{ 
// 请求失败 NSLog(@"请求失败 %@", error);
 }];

七、监控联网状态
1.AFN监控联网状态
联网状态status

// 2.设置监听
AFNetworkReachabilityStatusUnknown = -1, 未识别 AFNetworkReachabilityStatusNotReachable = 0, 未连接 AFNetworkReachabilityStatusReachableViaWWAN = 1, 3G AFNetworkReachabilityStatusReachableViaWiFi = 2, wifi

示例代码

AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
// 提示:要监控网络连接状态,必须要先调用单例的startMonitoring方法[manager startMonitoring];
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus 

2.Reachability监控联网状态苹果提供,导入这两个类使用

// 1.检测wifi状态 
Reachability *wifi = [Reachability reachabilityForLocalWiFi]; 
// 2.检测手机是否能上网络(WIFI\3G\2.5G) 
Reachability *conn = [Reachability reachabilityForInternetConnection]; 
// 3.判断网络状态 if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi NSLog(@"有wifi"); } else if ([conn currentReachabilityStatus] != NotReachable) { // 没有使用wifi, 使用手机自带网络进行上网 NSLog(@"使用手机自带网络进行上网"); } else { // 没有网络 NSLog(@"没有网络"); }

①判断联网状态

// 用WIFI
// [wifi currentReachabilityStatus] != NotReachable
// [conn currentReachabilityStatus] != NotReachable
// 没有用WIFI, 只用了手机网络
// [wifi currentReachabilityStatus] == NotReachable
// [conn currentReachabilityStatus] != NotReachable
// 没有网络
// [wifi currentReachabilityStatus] == NotReachable
//[conn currentReachabilityStatus] == NotReachable

②实时监听网络状态

#import "ViewController.h"
#import "Reachability.h"
@interface HMViewController ()
@property (nonatomic, strong) Reachability *conn;
@end

@implementation HMViewController

- (void)viewDidLoad
{ 
[super viewDidLoad]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkState) 
name:kReachabilityChangedNotification object:nil]; 

self.conn = [Reachability reachabilityForInternetConnection]; [self.conn startNotifier];
}

- (void)dealloc{ [self.conn stopNotifier]; 
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)checkNetworkState{ 
// 1.检测wifi状态 
Reachability *wifi = [Reachability reachabilityForLocalWiFi]; 
// 2.检测手机是否能上网络(WIFI\3G\2.5G) 
Reachability *conn = [Reachability reachabilityForInternetConnection]; 
// 3.判断网络状态
 if ([wifi currentReachabilityStatus] != NotReachable) { 
// 有wifi NSLog(@"有wifi"); 
} else if ([conn currentReachabilityStatus] != NotReachable) { 

// 没有使用wifi, 使用手机自带网络进行上网 NSLog(@"使用手机自带网络进行上网");
} else { 
// 没有网络 NSLog(@"没有网络"); 
}}
@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,561评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,218评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,162评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,470评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,550评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,806评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,951评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,712评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,166评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,510评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,643评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,306评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,930评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,745评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,983评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,351评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,509评论 2 348

推荐阅读更多精彩内容