勤之時 - 網(wǎng)絡(luò)層的實現(xiàn)

應(yīng)用很早就上線了,歡迎大家下載使用:http://itunes.apple.com/app/id1206687109
源碼已經(jīng)公開纹份,大家可以去https://github.com/Inspirelife96/ILDiligence下載抵恋。 喜歡的話Fork或者給個Star果漾,非常感謝大渤。
下面是這一系列的全部帖子:
想法和原型
勤之時 - 架構(gòu)與工程組織結(jié)構(gòu)
勤之時 - 數(shù)據(jù)持久層的實現(xiàn)
勤之時 - 網(wǎng)絡(luò)層的實現(xiàn)
勤之時 - 業(yè)務(wù)邏輯層
勤之時 - Info.plist的改動
勤之時 - 表示層(一)
勤之時 - 表示層(二)
勤之時 - 表示層(三)
勤之時 - 表示層(四)
勤之時 - 表示層(五)

事實上缰盏,【勤之時】一個本地應(yīng)用惑芭,基本上沒有什么網(wǎng)絡(luò)請求坠狡,或者需要從服務(wù)器端下載數(shù)據(jù)。不過為了美觀遂跟,每天的背景圖片會變化逃沿,并且會有一個每日故事的分享頁面,也就是說幻锁,每天一圖凯亮。

網(wǎng)絡(luò)層需求.png

那么具體這個圖片怎么來?當(dāng)然可以自己搭建服務(wù)器哄尔,然后提供圖片假消。不過這樣相對來說比較復(fù)雜,不但要搭建服務(wù)器岭接,還要自己準(zhǔn)備圖片富拗。所以最簡單的是看有沒有現(xiàn)成的API 服務(wù),我找到了兩個:

  1. Bing 的每日一圖
  2. Unsplash API

Bing的每日一圖并不是API服務(wù)鸣戴,不過通過抓包啃沪,可以發(fā)現(xiàn)http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1 可以獲取到無水印的圖片。


{
    "images": [{
                   "startdate":"20170319",
                   "fullstartdate":"201703191600",
                   "enddate":"20170320",
                   "url":"/az/hprichbg/rb/TingSakura_ZH-CN14945610051_1920x1080.jpg",
                   "urlbase":"/az/hprichbg/rb/TingSakura_ZH-CN14945610051",
                   "copyright":"一只在櫻花樹上嬉戲的綠繡眼(? Reece Cheng/500px)",
                   "copyrightlink":"http://www.bing.com/search?q=%E6%98%A5%E5%88%86&form=hpcapt&mkt=zh-cn",
                   "quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20170319_TingSakura%22&FORM=HPQUIZ",
                   "wp":true,
                   "hsh":"c4afb61170efde716ed371c02f8db13f","drk":1,"top":1,"bot":1,"hs":[]
               }],
    "tooltips": {
        "loading":"正在加載...",
        "previous":"上一個圖像",
        "next":"下一個圖像",
        "walle":"此圖片不能下載用作壁紙窄锅。",
        "walls":"下載今日美圖创千。僅限用作桌面壁紙。"
    }
}

從返回的Json中可以看到入偷,我們可以獲取到urlbase追驴,經(jīng)過測試,bing提供了1080x1920的圖片疏之,其后綴為_1080x1920.jpg殿雪,所以最后無水印圖片的下載地址為http://www.bing.com/urlbase_1080x1920.jpg

那么當(dāng)前圖片對應(yīng)的故事在哪里呢体捏?同樣發(fā)現(xiàn)了API接口http://cn.bing.com/cnhp/coverstory/冠摄,不過這里的圖片是有水印的糯崎。

{
    "date":"March 20",
    "title":"碧玉妝 綠絲絳",
    "attribute":"枝頭嬉戲的綠繡眼",
    "para1":"古代的春分分為三候:“一候玄鳥至,二候雷乃發(fā)聲河泳,三候始電沃呢。”便是說春分日后拆挥,燕子便從南方飛來了薄霜,下雨時天空便要打雷并發(fā)出閃電。春分后纸兔,中國南方大部分地區(qū)越冬作物進(jìn)入春季生長階段惰瓜,氣溫也繼續(xù)回升,真正的春天來了汉矿,你也開始一個全新的自己吧崎坊!",
    "para2":"",
    "provider":"? Reece Cheng/500px",
    "imageUrl":"/th?id=OSA.pfFS41jcab0yuA&pid=SatAns&w=100&h=100&c=8&rs=1","primaryImageUrl":"http://hpimges.blob.core.chinacloudapi.cn/coverstory/watermark_tingsakura_zh-cn14945610051_1920x1080.jpg",
    "Country":"",
    "City":"",
    "Longitude":"",
    "Latitude":"",
    "Continent":"亞洲",
    "CityInEnglish":"Enter keyword",
    "CountryCode":""
}

所以綜合這兩個,我們就可以得到每日背景圖片及故事洲拇。

至于Unsplash奈揍,大家可以參考Unsplash官網(wǎng)的說明去試試「承【勤之時】暫時使用的是Bing的每日一圖及故事來作為背景男翰。

知道了需求,了解了內(nèi)容的來源纽乱,接下來就是如何實現(xiàn)了蛾绎。同樣,iOS應(yīng)用架構(gòu)談 網(wǎng)絡(luò)層設(shè)計方案探討了詳細(xì)的方案鸦列。

最終的方案

  1. 使用delegate來做數(shù)據(jù)對接
  2. 交付NSDictionary給業(yè)務(wù)層租冠,使用Const字符串作為Key來保持可讀性

此外,【勤之時】的需求涉及到同步問題敛熬,可以發(fā)現(xiàn)肺稀,我們的操作為

  1. 訪問http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1 獲取Json數(shù)據(jù)
  2. 根據(jù)Json數(shù)據(jù)拼接獲得每日圖片的下載地址
  3. 下載圖片
  4. 訪問http://cn.bing.com/cnhp/coverstory/獲取每日故事的內(nèi)容第股。

可以發(fā)現(xiàn)应民,我們會發(fā)送3個HTTP異步請求,只有當(dāng)三個請求全部成功返回后夕吻,我們才能認(rèn)為這個下載任務(wù)完成诲锹。因此,需要使用dispatch_group_t涉馅, dispatch_group_enter归园, dispatch_group_leave,dispatch_group_notify來完成這個組合稚矿。

最終代碼:

//  ILDNetwork.h

#import <Foundation/Foundation.h>

@protocol ILDNetworkDelegate <NSObject>

- (void)fetchStoryDataSuccess:(NSDictionary *)storyDataDictionary;
- (void)fetchStoryDataFail:(NSError * _Nonnull)error;

@end

@interface ILDNetwork : NSObject

@property (nonatomic,weak) id<ILDNetworkDelegate> delegate;

- (void)downloadStoryData;

@end

![
![網(wǎng)絡(luò)層需求.png](http://upload-images.jianshu.io/upload_images/1771779-726f82b81d60f3da.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](http://upload-images.jianshu.io/upload_images/1771779-541fcb4c8382a9f2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)//  ILDNetwork.m

#import "ILDNetwork.h"
#import "ILDNetworkConstants.h"
#import <UIKit/UIKit.h>
#import <AFNetworking/AFNetworking.h>

@interface ILDNetwork()

@property (nonatomic, strong) dispatch_group_t requestGroup;

@property (nonatomic, strong) NSString *storyTitle;
@property (nonatomic, strong) NSString *storyAttribute;
@property (nonatomic, strong) NSString *storyPara1;
@property (nonatomic, strong) UIImage *storyImage;
@property (nonatomic, strong) NSError *error;

@end


@implementation ILDNetwork

- (void)downloadStoryData {
    [self downloadImageData];
    [self downloadOtherData];
    
    dispatch_group_notify(self.requestGroup, dispatch_get_main_queue(), ^{
        if (!self.error) {
            [self.delegate fetchStoryDataFail:self.error];
        } else {
            NSDictionary *storyDataDictionary = @{
                                                  kBingStoryURLTitle:self.storyTitle,
                                                  kBingStoryURLAttribute:self.storyAttribute,
                                                  kBingStoryURLPara1:self.storyPara1,
                                                  kBingImageURLImageData:UIImageJPEGRepresentation(self.storyImage, 0.5)
                                                  };
            [self.delegate fetchStoryDataSuccess:storyDataDictionary];
        }
    });
}

- (void)downloadImageData {
    dispatch_group_enter(self.requestGroup);
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
    NSURL *URL = [NSURL URLWithString:kBingImageURL];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
    NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        if (error) {
            self.error = error;
        } else {
            NSDictionary *responseDict = (NSDictionary *)responseObject[kBingImageURLImages][0];
            NSString *imageURLString = [NSString stringWithFormat:kBingImageFullPathFormat, responseDict[kBingImageURLUrlBase], kImageTypes];
            [self downloadImageData:imageURLString];
        }
        dispatch_group_leave(self.requestGroup);
    }];
    
    [dataTask resume];
}

- (void)downloadImageData:(NSString *)imageUrlString {
    dispatch_group_enter(self.requestGroup);
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    manager.responseSerializer = [AFImageResponseSerializer serializer];
    
    NSURL *URL = [NSURL URLWithString:imageUrlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
    NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        if (error) {
            self.error = error;
        } else {
            self.storyImage = responseObject;
        }
        dispatch_group_leave(self.requestGroup);
    }];
    
    [dataTask resume];
}

- (void)downloadOtherData {
    dispatch_group_enter(self.requestGroup);
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
    NSURL *URL = [NSURL URLWithString:kBingStoryURL];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
    NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        if (error) {
            self.error = error;
        } else {
            NSDictionary *responseDict = (NSDictionary *)responseObject;
            self.storyTitle = responseDict[kBingStoryURLTitle];
            self.storyAttribute = responseDict[kBingStoryURLAttribute];
            self.storyPara1 = responseDict[kBingStoryURLPara1];
        }
        dispatch_group_leave(self.requestGroup);
    }];
    
    [dataTask resume];
}

- (dispatch_group_t)requestGroup {
    if (!_requestGroup) {
        _requestGroup = dispatch_group_create();
    }
    
    return _requestGroup;
}

@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末庸诱,一起剝皮案震驚了整個濱河市捻浦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桥爽,老刑警劉巖朱灿,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钠四,居然都是意外死亡盗扒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門缀去,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侣灶,“玉大人,你說我怎么就攤上這事缕碎∪煊埃” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵咏雌,是天一觀的道長伪阶。 經(jīng)常有香客問我,道長处嫌,這世上最難降的妖魔是什么栅贴? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮熏迹,結(jié)果婚禮上檐薯,老公的妹妹穿的比我還像新娘。我一直安慰自己注暗,他們只是感情好坛缕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捆昏,像睡著了一般赚楚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骗卜,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天宠页,我揣著相機(jī)與錄音,去河邊找鬼寇仓。 笑死举户,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的遍烦。 我是一名探鬼主播俭嘁,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼服猪!你這毒婦竟也來了供填?” 一聲冷哼從身側(cè)響起拐云,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎近她,沒想到半個月后慨丐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泄私,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年房揭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晌端。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡捅暴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出咧纠,到底是詐尸還是另有隱情蓬痒,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布漆羔,位于F島的核電站梧奢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏演痒。R本人自食惡果不足惜亲轨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸟顺。 院中可真熱鬧惦蚊,春花似錦、人聲如沸讯嫂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽欧芽。三九已至莉掂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間千扔,已是汗流浹背憎妙。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留昏鹃,地道東北人尚氛。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像洞渤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子属瓣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

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