iOS網(wǎng)絡(luò)基礎(chǔ)——NSURLConnection使用詳解舉例

一鲸沮、整體介紹

NSURLConnection是蘋果提供的原生網(wǎng)絡(luò)訪問類诺凡,但是蘋果很快會將其廢棄沸柔,且由NSURLSession(iOS7以后)來替代暑刃。目前使用最廣泛的第三方網(wǎng)絡(luò)框架AFNetworking最新版本已棄用了NSURLConnection勤讽,那我們學(xué)習(xí)它還有什么用呢竹宋?

  • 首先,蘋果棄用它還是需要時間的地技,最起碼到iOS10之后蜈七;
  • 現(xiàn)在還有一些老項(xiàng)目會使用NSURLConnection,特別是2013年之前的項(xiàng)目莫矗,用戶量基礎(chǔ)還是很大的飒硅;
  • 另外,不得不承認(rèn)作谚,有些公司還在用類似ASI這些經(jīng)典的網(wǎng)絡(luò)框架三娩,所以還是很有必要學(xué)習(xí)NSURLConnection的。

二妹懒、使用的一般步驟

1 NSURL:請求地址雀监,定義一個網(wǎng)絡(luò)資源路徑:

NSURL *url = [NSURL URLWithString:@"協(xié)議://主機(jī)地址/路徑?參數(shù)&參數(shù)"];

解釋如下:

  • 協(xié)議:不同的協(xié)議,代表著不同的資源查找方式眨唬、資源傳輸方式会前,比如常用的http,ftp等
  • 主機(jī)地址:存放資源的主機(jī)的IP地址(域名)
  • 路徑:資源在主機(jī)中的具體位置
  • 參數(shù):參數(shù)可有可無匾竿,也可以多個瓦宜。如果帶參數(shù)的話,用“?”號后面接參數(shù)岭妖,多個參數(shù)的話之間用&隔開

2 NSURLRequest:請求临庇,根據(jù)前面的NSURL建立一個請求:

NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];

參數(shù)解釋如下:

  • url:資源路徑
  • cachePolicy:緩存策略(無論使用哪種緩存策略,都會在本地緩存數(shù)據(jù))昵慌,類型為美劇類型假夺,取值如下:
    • NSURLRequestUseProtocolCachePolicy = 0 //默認(rèn)的緩存策略,使用協(xié)議的緩存策略
    • NSURLRequestReloadIgnoringLocalCacheData = 1 //每次都從網(wǎng)絡(luò)加載
    • NSURLRequestReturnCacheDataElseLoad = 2 //返回緩存否則加載斋攀,很少使用
    • NSURLRequestReturnCacheDataDontLoad = 3 //只返回緩存已卷,沒有也不加載,很少使用
  • timeoutInterval:超時時長蜻韭,默認(rèn)60s

另外悼尾,還可以設(shè)置其它一些信息柿扣,比如請求頭肖方,請求體等等闺魏,如下:

注意,下面的request應(yīng)為NSMutableURLRequest俯画,即可變類型

// 告訴服務(wù)器數(shù)據(jù)為json類型
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
// 設(shè)置請求體(json類型)
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:@{@"userid":@"123456"} options:NSJSONWritingPrettyPrinted error:nil];
request.HTTPBody = jsonData; 

3 發(fā)送請求:

NSURLConnection默認(rèn)的請求類型為GET析桥,下面分異步和同步兩種介紹

異步請求
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    // 有的時候,服務(wù)器訪問正常艰垂,但是會沒有數(shù)據(jù)泡仗!
    // 以下的 if 是比較標(biāo)準(zhǔn)的錯誤 處理代碼!
    if (connectionError != nil || data == nil) {
        //給用戶的提示信息
        NSLog(@"網(wǎng)絡(luò)不給力");
        return;
    }
}];

參數(shù)說明如下:

  • completionHandler:請求響應(yīng)后(或者請求超時)執(zhí)行的代碼猜憎,queue為代碼添加到的隊(duì)列娩怎,即block執(zhí)行的線程
    • NSURLResponse 為服務(wù)器的響應(yīng),真實(shí)類型為NSHTTPURLResponse胰柑,通常只在“下載”功能時截亦,才會使用;下面是協(xié)議頭的參數(shù):
      • URL:響應(yīng)的URL柬讨,有的時候崩瓤,訪問一個URL地址,服務(wù)器可能會出現(xiàn)重定向踩官,會定位到新的地址却桶!
      • MIMEType(Content-Type):服務(wù)器告訴客戶端,可以用什么軟件打開二進(jìn)制數(shù)據(jù)蔗牡!網(wǎng)絡(luò)之所以豐富多采颖系,是因?yàn)橛胸S富的客戶端軟件!栗子:windows上提示安裝 Flash 插件
      • expectedContentLength:預(yù)期的內(nèi)容長度辩越,要下載的文件長度集晚,下載文件時非常有用
      • suggestedFilename:"建議"的文件名,方便用戶直接保存区匣,很多時候偷拔,用戶并不關(guān)心要保存成什么名字!
      • textEncodingName:文本的編碼名稱 @"UTF8"亏钩,大多數(shù)都是 UTF8
      • statusCode:狀態(tài)碼莲绰,在做下載操作的時候,需要判斷一下
      • allHeaderFields:所有的響應(yīng)頭字典時候姑丑,用戶并不關(guān)心要保存成什么名字蛤签!
    • NSData 服務(wù)器返回的數(shù)據(jù),例如json栅哀、xml(現(xiàn)在用的少)
    • NSError 網(wǎng)絡(luò)訪問錯誤碼

注意震肮,block的執(zhí)行線程為queue称龙,如果block涉及到UI操作,則必須回到主線程:[NSOperationQueue mainQueue]

發(fā)送同步請求
// 同步請求戳晌,代碼會阻塞在這里一直等待服務(wù)器返回鲫尊,如果data為nil則請求失敗,當(dāng)獲取少量數(shù)據(jù)時可以使用此方法沦偎。
// request參數(shù)同上疫向。
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 

三、舉例說明

分三個部分:

  1. 網(wǎng)絡(luò)請求(json豪嚎、xml數(shù)據(jù))
  2. 文件下載
  3. 文件上傳搔驼,這里例子不再給出,請參考這里:文件上傳

1 一般的網(wǎng)絡(luò)請求

/// 兩種請求方式
typedef enum {
    MethodGET,
    MethodPOST
}Method;

/// 請求成功后侈询,直接將jsonData轉(zhuǎn)為jsonDict
+ (void)connectionRequestWithMethod:(Method)method   URLString:(NSString *)URLString parameters:(NSDictionary *)dict success:(void (^)(id JSON))success fail:(void (^)(NSError *error))fail {
    URLString = [URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    // 1.創(chuàng)建請求
    NSURL *url = [NSURL URLWithString:URLString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 請求方式舌涨,默認(rèn)為GET
    if (method == MethodPOST) {
        request.HTTPMethod = @"POST";
    }
    // 根據(jù)需要設(shè)置
    [request setValue:@"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" forHTTPHeaderField:@"Accept"];
    
    // 2.設(shè)置請求頭 Content-Type  返回格式
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
    // 3.設(shè)置請求體 NSDictionary --> NSData
    if (dict != nil) {
        NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
        request.HTTPBody = data;
    }
    // 4.發(fā)送請求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if ((data != nil) && (connectionError == nil)) {
            NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            if (success) {
                success(jsonDict);
            }
        } else {
            if (fail) {
                fail(connectionError);
            }
        }
        
    }];
}

2 文件下載

下面舉一個實(shí)現(xiàn)斷點(diǎn)續(xù)傳的網(wǎng)絡(luò)下載,要實(shí)現(xiàn)斷點(diǎn)續(xù)傳扔字,還需要用到NSURLConnectionDataDelegate代理囊嘉,NSFileHandle文件操作或者數(shù)據(jù)流的形式(NSOutputStream),這里以NSFileHandle為例啦租,訪問的服務(wù)器采用Apache搭建的本地服務(wù)器哗伯,具體見代碼:

@interface ViewController () <NSURLConnectionDataDelegate>

/// 文件下載完畢之后,在本地保存的路徑
@property (nonatomic, copy) NSString *filePath;
/// 需要下載的文件的總大小!
@property (nonatomic, assign) long long serverFileLength;
/// 當(dāng)前已經(jīng)下載長度
@property (nonatomic, assign) long long localFileLength;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];    
}
/// 點(diǎn)擊屏幕事件
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self downloadFile];
}
/// 下載文件
- (void)downloadFile {
    // 文件存儲路徑
    self.filePath = @"/Users/username/Desktop//陶喆 - 愛很簡單.mp3";
    // 要下載的網(wǎng)絡(luò)文件,采用Apache搭建的本地服務(wù)器
    NSString *urlStr = @"http://localhost/陶喆 - 愛很簡單.mp3";
    urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *url = [NSURL URLWithString:urlStr];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 設(shè)置請求方法為 HEAD 方法篷角,這里只是頭焊刹,數(shù)據(jù)量少,用同步請求也可以恳蹲,不過最好還是用異步請求
    request.HTTPMethod = @"HEAD";
    // 無論是否會引起循環(huán)引用虐块,block里面都使用弱引用
    __weak typeof(self) weakSelf = self;
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        // 出錯則返回
        if (connectionError != nil) {
            NSLog(@"connectionError = %@",connectionError);
            return ;
        }
        // 記錄需要下載的文件總長度
        long long serverFileLength = response.expectedContentLength;
        weakSelf.serverFileLength = serverFileLength;
        // 初始化已下載文件大小
        weakSelf.localFileLength = 0;
        
        NSDictionary *dict = [[NSFileManager defaultManager] attributesOfItemAtPath:weakSelf.filePath error:NULL];
        
        long long  localFileLength = [dict[NSFileSize] longLongValue];
        
        // 如果沒有本地文件,直接下載!
        if (!localFileLength) {
            // 下載新文件
            [weakSelf getFileWithUrlString:urlStr];
        }
        // 如果已下載的大小,大于服務(wù)器文件大小嘉蕾,肯定出錯了贺奠,刪除文件并從新下載
        if (localFileLength > serverFileLength) {
            // 刪除文件 remove
            [[NSFileManager defaultManager]  removeItemAtPath:self.filePath error:NULL];
            
            // 下載新文件
            [self getFileWithUrlString:urlStr];
            
        } else if (localFileLength == serverFileLength) {
            NSLog(@"文件已經(jīng)下載完畢");
        } else if (localFileLength && localFileLength < serverFileLength) {
            // 文件下載了一半,則使用斷點(diǎn)續(xù)傳
            self.localFileLength = localFileLength;
            
            [self getFileWithUrlString:urlStr WithStartSize:localFileLength endSize:serverFileLength-1];
        }
    }];
    
}
/// 重新開始下載文件(代理方法監(jiān)聽下載過程)
-(void)getFileWithUrlString:(NSString *)urlString
{
    NSURL *url = [NSURL URLWithString:urlString];
    // 默認(rèn)就是 GET 請求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 開始請求错忱,并設(shè)置代理為self
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    
    // 設(shè)置代理的執(zhí)行線程儡率,一般不在主線程
    [conn setDelegateQueue:[[NSOperationQueue alloc] init]];
    
    // NSUrlConnection 的代理方法是一個特殊的事件源!
    // 開啟運(yùn)行循環(huán)!
    CFRunLoopRun();
}

/* 斷點(diǎn)續(xù)傳(代理方法監(jiān)聽下載過程)
 * startSize:本次斷點(diǎn)續(xù)傳開始的位置
 * endSize:本地?cái)帱c(diǎn)續(xù)傳結(jié)束的位置
 */
-(void)getFileWithUrlString:(NSString *)urlString WithStartSize:(long long)startSize endSize:(long long)endSize
{
    // 1. 創(chuàng)建請求!
    NSURL *url = [NSURL URLWithString:urlString];
    // 默認(rèn)就是 GET 請求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    // 設(shè)置斷點(diǎn)續(xù)傳信息
    NSString *range = [NSString stringWithFormat:@"Bytes=%lld-%lld",startSize,endSize];
    [request setValue:range forHTTPHeaderField:@"Range"];
    
    // NSUrlConnection 下載過程!
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    
    // 設(shè)置代理的執(zhí)行線程// 傳一個非主隊(duì)列!
    [conn setDelegateQueue:[[NSOperationQueue alloc] init]];
    
    // NSUrlConnection 的代理方法是一個特殊的事件源!
    // 開啟運(yùn)行循環(huán)!
    CFRunLoopRun();
}

#pragma mark - NSURLConnectionDataDelegate
/// 1. 接收到服務(wù)器響應(yīng)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    // 服務(wù)器響應(yīng)
    // response.expectedContentLength的大小是要下載文件的大小,而不是文件的總大小以清。比如請求頭設(shè)置了Range[requestM setValue:rangeStr forHTTPHeaderField:@"Range"];則返回的大小為range范圍內(nèi)的大小
}
/// 2. 接收到數(shù)據(jù)
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    //data當(dāng)前接收到的網(wǎng)絡(luò)數(shù)據(jù);
    // 如果這個文件不存在,響應(yīng)的文件句柄就不會創(chuàng)建!
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.filePath];
    // 在這個路徑下已經(jīng)有文件了!
    if (fileHandle) {
        // 將文件句柄移動到文件的末尾
        [fileHandle seekToEndOfFile];
        // 寫入文件的意思(會將data寫入到文件句柄所操縱的文件!)
        [fileHandle writeData:data];
        
        [fileHandle closeFile];
        
    } else {
        // 第一次調(diào)用這個方法的時候,在本地還沒有文件路徑(沒有這個文件)!
        [data writeToFile:self.filePath atomically:YES];
    }
}
/// 3. 接收完成
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"下載完成");
}
/// 4. 網(wǎng)絡(luò)錯誤
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"下載錯誤 %@", error);
}
@end

四儿普、NSData 數(shù)據(jù)的反序列化

服務(wù)器返回的NSData數(shù)據(jù)類型,事先已經(jīng)知道掷倔,因此可以直接返序列化為實(shí)際的類型眉孩,例如:json(字典或數(shù)組).plist(字典或數(shù)組)text浪汪、xml等:

  • 加載數(shù)據(jù)
// 加載本地
NSString *path = [[NSBundle mainBundle] pathForResource:@"文件名 " ofType:nil];
NSData *jsonData = [NSData dataWithContentsOfFile:path];

// 從網(wǎng)絡(luò)直接加載
NSURL *url = [[NSBundle mainBundle] URLForResource:@"topic_news.json" withExtension:nil];
NSData *data = [NSData dataWithContentsOfURL:url];

  • .plist反序列化

這種很少使用巴柿,只是蘋果自己的格式

// 關(guān)于選型參數(shù)
// NSPropertyListImmutable = 0,不可變  
// NSPropertyListMutableContainers = 1 << 0,容器可變
// NSPropertyListMutableContainersAndLeaves = 1 << 1,容器和葉子可變
// 通常后續(xù)直接做字典轉(zhuǎn)模型,不需要關(guān)心是否可變,所以一般直接賦值為0
id result = [NSPropertyListSerialization propertyListWithData:data options:0 format:NULL error:NULL];
  • 關(guān)于json數(shù)據(jù)

    • json數(shù)據(jù)的本質(zhì)是字符串死遭,根格式只有兩種可能:數(shù)組或字典广恢。

      • 反序列化:從服務(wù)器接收到的二進(jìn)制數(shù)據(jù) 轉(zhuǎn)換成 字典或者數(shù)組
      // 假設(shè)json數(shù)據(jù)位:[{鍵值對},{鍵值對}],則可以將數(shù)據(jù)轉(zhuǎn)化為字典或數(shù)組
      

    NSArray *dictArray = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
    ```

      - 序列化:將字典或者數(shù)組 轉(zhuǎn)換成 二進(jìn)制數(shù)據(jù)殃姓,準(zhǔn)備發(fā)送給服務(wù)器  
    
      ```objc
    

// obj為字典或數(shù)組
NSData *data = [NSJSONSerialization dataWithJSONObject:obj options:0 error:NULL];
// 轉(zhuǎn)化前可以判斷是否可以序列化:
(BOOL)isValidJSONObject:(id)obj;
```
* 一個對象能夠被轉(zhuǎn)換成 JSON 必須符合以下條件:
- 頂級節(jié)點(diǎn)袁波,必須是一個 NSArray or NSDictionary
- 所有的對象必須是 NSString, NSNumber, NSArray, NSDictionary, or NSNull
- 所有字典的 key 都必須是 NSString
- NSNumber 不能為空或者無窮大

注意事項(xiàng):

  • 請求的緩存策略使用 NSURLRequestReloadIgnoringCacheData瓦阐,忽略本地緩存
  • 服務(wù)器響應(yīng)結(jié)束后蜗侈,要記錄 Etag,服務(wù)器內(nèi)容和本地緩存對比是否變化的重要依據(jù)睡蟋!
  • 在發(fā)送請求時踏幻,設(shè)置 If-None-Match,并且傳入 etag
  • 連接結(jié)束后戳杀,要判斷響應(yīng)頭的狀態(tài)碼该面,如果是 304,說明本地緩存內(nèi)容沒有發(fā)生變化,此時可以使用本地緩存來加載數(shù)據(jù)信卡,如果緩存文件被意外刪除隔缀,程序依然運(yùn)行但會報錯仔引,加載數(shù)據(jù)也失斝椒:
NSCachedURLResponse *cachedURLRes = [[NSURLCache sharedURLCache] cachedResponseForRequest:requestM];//cachedURLRes為nil
  • GET 緩存的數(shù)據(jù)會保存在 Cache 目錄中 /bundleId 下,Cache.db 中

iOS9訪問http網(wǎng)頁

  1. 在Info.plist中添加NSAppTransportSecurity類型Dictionary;
  2. 在NSAppTransportSecurity下添加NSAllowsArbitraryLoads類型Boolean,值設(shè)為YES

參考:http://www.cnblogs.com/mddblog/p/5134783.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末古话,一起剝皮案震驚了整個濱河市丢习,隨后出現(xiàn)的幾起案子牵触,更是在濱河造成了極大的恐慌,老刑警劉巖咐低,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揽思,死亡現(xiàn)場離奇詭異,居然都是意外死亡见擦,警方通過查閱死者的電腦和手機(jī)钉汗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲤屡,“玉大人损痰,你說我怎么就攤上這事≈戳” “怎么了徐钠?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長役首。 經(jīng)常有香客問我尝丐,道長显拜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任爹袁,我火速辦了婚禮远荠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘失息。我一直安慰自己譬淳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布盹兢。 她就那樣靜靜地躺著邻梆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绎秒。 梳的紋絲不亂的頭發(fā)上浦妄,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音见芹,去河邊找鬼剂娄。 笑死,一個胖子當(dāng)著我的面吹牛玄呛,可吹牛的內(nèi)容都是我干的阅懦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼徘铝,長吁一口氣:“原來是場噩夢啊……” “哼耳胎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起庭砍,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤场晶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后怠缸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诗轻,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年揭北,在試婚紗的時候發(fā)現(xiàn)自己被綠了扳炬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡搔体,死狀恐怖恨樟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疚俱,我是刑警寧澤劝术,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響养晋,放射性物質(zhì)發(fā)生泄漏衬吆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一绳泉、第九天 我趴在偏房一處隱蔽的房頂上張望逊抡。 院中可真熱鬧,春花似錦零酪、人聲如沸冒嫡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孝凌。三九已至,卻和暖如春蛔琅,著一層夾襖步出監(jiān)牢的瞬間胎许,已是汗流浹背峻呛。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工罗售, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钩述。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓寨躁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親牙勘。 傳聞我的和親對象是個殘疾皇子职恳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)方面,斷路器放钦,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 閱讀目錄 一、整體介紹 二恭金、使用的一般步驟 三操禀、舉例說明 四、NSData 數(shù)據(jù)的反序列化 注意事項(xiàng): iOS9訪...
    九洲仙人閱讀 793評論 0 0
  • iOS開發(fā)系列--網(wǎng)絡(luò)開發(fā) 概覽 大部分應(yīng)用程序都或多或少會牽扯到網(wǎng)絡(luò)開發(fā)横腿,例如說新浪微博颓屑、微信等,這些應(yīng)用本身可...
    lichengjin閱讀 3,657評論 2 7
  • AFHTTPRequestOperationManager 網(wǎng)絡(luò)傳輸協(xié)議UDP耿焊、TCP揪惦、Http、Socket罗侯、X...
    Carden閱讀 4,337評論 0 12
  • 最近又開始上演小鮮肉仙俠劇了器腋,追劇的時候怎能沒有啤酒和雞腳呀! 外面賣的那又白又胖的泡雞腳,你要是想好好的多活幾年...
    pauline布丁媽閱讀 651評論 4 7