MKNetworkKit框架入门及简单用法

来源:互联网 发布:捷易通软件 编辑:程序博客网 时间:2024/05/22 14:12

1.什么是MKNetWorkKit?

MKNetWorkKit是一个用OC语言编写的网络框架,支持block块和ARC;并且MKNetWorkKit的用法简单.

MKNetWorkKit是集成了ASIHTTPRequest和 AFNetworking

两个框架于一体,在集成两者的优点之外,自己还增加了很多新的特性.

2. MKNetWorkKit的优点

   1、整个框架只有一些类别方法和两个类(MKNetworkEngine和MKNetworkOperation)所以它使用起来很简便

   2、自主操作多个网络请求;

   3、更加准确的显示网络活动指标;

   4、自动设置网络速度,实现自动的2G、3G、wifi切换;

   5、自动缓冲技术的完美应用,实现网络操作记忆功能,当你掉线了又上线后,会继续执行未完成的网络请求;

   6、可以实现网络请求的暂停功能;

   7、准确无误的成功执行一次网络请求,摒弃后台的多次请求浪费;

   8、支持图片缓冲;

   9、支持ARC机制;

   10、在整个app中可以只用一个队列(queue),队列的大小可以自动调整。

3.如何配置MKNetworkKit?

   1、从https://github.com/MugunthKumar/MKNetworkKit下载MKNetworkKit;

   2、将下载包中的 MKNetWorkKit 文件夹拖到你新建的工程中;

   3、在项目设置中添加:SystemConfiguration.framework,CFNetwork.framework,Security.framework和ImageIO.framework

4.怎么进行网络请求?

MKNetworkKit中主要有两个类:MKNetworkOperation和MKNetworkEngine。MKNetworkOperation是NSOperation的子类并且封装了请求相应类,我们需要为每一个网络请求创建一个MKNetworkOperation。MKNetworkEngine负责管理网络队列,对于简单的请求,我们应该直接使用MKNetworkEngine的方法,对于复杂的需求,我们可以子类化MKNetworkEngine。

5.MKNetworkKit中的一些简便用法

MKNetworkKit的一些简便用法:

1.           responseData

2.           responseString

3.           responseJSON (Only on iOS 5以上)

4.           responseImage

5.           responseXML

6.           error

6.一个利用MKNetworkKit网络请求(GET请求)的天气预报DEMO

效果图:

效果图

 //请求路径.是在主机名之后显示的,可以与主机名进行拼接,拼接成一个完整的url    NSString *path = [[NSString alloc] initWithFormat:@"//data/sk/%@.html",cityID];        //创建一个MKNetworkEngine对象,注意initWithHostName后面是主机名    //.....MKNetworkEngine负责管理网络队列NSOperationQueue    __block MKNetworkEngine *engine = [[MKNetworkEngine alloc] initWithHostName:@"www.weather.com.cn" customHeaderFields:nil];    //创建一个MKNetworkOperation对象    //MKNetworkOperation是NSOperation的子类并且封装了请求相应类    //在进行网络请求是需要为每一个网络请求创建一个MKNetworkOperation    MKNetworkOperation *op = [engine operationWithPath:path params:nil httpMethod:@"GET"];        //指定请求的代码块,网络请求成功时回调代码块addCompletionHandler,失败时回调errorHandler的block代码块    [op addCompletionHandler:^(MKNetworkOperation *completedOperation) {        //通过MKNetworkOperation中的responseData方法直接获取url中的数据.并且存放在NSData中//        NSData *data = [completedOperation responseData];//        //对拿到的数据进行json解析,系统给出的json解析//        result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];//        result = [result objectForKey:@"weatherinfo"];        //利用MKNetworkKit给的json解析进行解析数据        result =  [[completedOperation responseJSON] objectForKey:@"weatherinfo"];        self.cityLabel.text = [result objectForKey:@"city"];        self.tempLabel.text = [result objectForKey:@"temp"];        self.wdLabel.text = [result objectForKey:@"WD"];        self.wlLabel.text = [result objectForKey:@"WS"];        self.sdLabel.text = [result objectForKey:@"SD"];        self.timeLabel.text = [result objectForKey:@"time"];                } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {                NSLog(@"%@",[error localizedDescription]);                engine = nil;            }];    //发起网络请求    [engine enqueueOperation:op];

post请求

效果图:


 // 转成专门用于URL的格式www.weather.com.cn/data/sk/101010300.html   101010300是城市ID    NSString *host = @"www.weather.com.cn";    // 域名(host)后面跟着的路径,    NSString *path = [NSString stringWithFormat:@"//data/sk/%@.html",cityID];        // 目标URL:www.weather.com.cn/data/sk/101010300.html        // 需要发送的参数    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];    [params setValue:cityID forKey:@"cityID"];        // path 值可以放到 engine 的初始化中,也可以放到 operation 的初始化中,效果一样    MKNetworkEngine *engine = [[MKNetworkEngine alloc] initWithHostName:host apiPath:path customHeaderFields:nil];    MKNetworkOperation *operation = [engine operationWithPath:nil params:params httpMethod:@"POST"];        // 添加网络请求完成处理逻辑    [operation addCompletionHandler:^(MKNetworkOperation *completedOperation) {        NSLog(@"POST请求完成");                self.wetherText.text = [completedOperation responseString];    } errorHandler:^(MKNetworkOperation *completedOperation, NSError *error) {        NSLog(@"POST请求出错");                self.wetherText.text = [NSString stringWithFormat:@"请求出错: %@", error];    }];        // 发送网络请求    [engine enqueueOperation:operation];

下载文件

效果如下图:

核心代码:
- (IBAction)LoadButton:(UIButton *)sender {//获取缓存路径.    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);    NSString *cachepath = [paths objectAtIndex:0];//得到缓存的路径    //进行拼接得到文件下载后缓存的路径    NSString *downloadPath = [cachepath stringByAppendingString:@"mmm.zip"];    [_engine addDownLoadTaskInQueue:url tofilePath:downloadPath breakpointResum:YES     rewriteFile:(BOOL)NO];}- (IBAction)pauseButton:(UIButton *)sender {    [_engine cancelDownloadFileTaskInQueue:url];}- (IBAction)deleteButton:(UIButton *)sender {    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);    NSString *cachepath = [paths objectAtIndex:0];//得到缓存的路径    //进行拼接得到文件下载后缓存的路径    NSString *downloadPath = [cachepath stringByAppendingString:@"mmm.zip"];    NSFileManager *fileManage = [NSFileManager defaultManager];    if ([fileManage fileExistsAtPath:downloadPath]) {        [fileManage removeItemAtPath:downloadPath error:nil];    }}

子类化的MKNetworkEngine:
.h文件
#import "MKNetworkEngine.h"@class DownLoadEngine;@class DownLoadOperation;@protocol DownLoadEngineDelegate//创建一个改变progress的方法- (void)changeprogress:(double)changeProgress         withOperation:(DownLoadOperation *)operation            withEngine:(DownLoadEngine *)engine;//下载完成时- (void)downloadEngineDidFinsh:(DownLoadEngine*)engine                 withOperation:(DownLoadOperation *)operation;//下载任务已经存在- (void)downloadEngineDownloadExist:(DownLoadEngine *)engine                             withURL:(NSString *)paramURL;//下载文件已经存在- (void)downloadEngineDownloadDone:(DownLoadEngine *)engine                            withURL:(NSString *)paramURL;//暂停下载- (void)downloadEnginePauseTask:(DownLoadEngine *)engine                         withURL:(NSString *)paramURL;@end@interface DownLoadEngine : MKNetworkEngine@property(nonatomic,retain)NSMutableArray *allDownloads;//用来存放任务的数组@property(nonatomic,assign)id<DownLoadEngineDelegate> delegate;//DownLoadEngine的单例方法+ (id)sharDownLoadEngine;//暂停所有任务的方法- (void)cancelAllOperations;//将所有的下载任务放到一个队列中- (void)addDownLoadTaskInQueue:(NSString *)urlString//要下载的文件的url路径                    tofilePath:(NSString *)paramPath////paramFilePath是下载的文件下载完存放的路径.               breakpointResum:(BOOL)resum                   rewriteFile:(BOOL)paramRewrite;//是否支持断点续传- (void)cancelDownloadFileTaskInQueue:(NSString *)paramURL;//暂停或取消指定的任务的方法


.m文件
- (void)addDownLoadTaskInQueue:(NSString *)urlString                    tofilePath:(NSString *)paramPath               breakpointResum:(BOOL)resum                   rewriteFile:(BOOL)paramRewrite{    //获得临时文件的路径    // 获取主目录下的tmp目录路径,用来存放下载的文件的临时文件(缓存路径)    NSString *temPath = NSTemporaryDirectory();    NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"/"];    NSRange lastRange = [paramPath rangeOfCharacterFromSet:set options:NSBackwardsSearch];    //拼接得到下载文件的缓存目录    NSString *temfilePath = [NSString stringWithFormat:@"%@%@.temp",temPath,[paramPath substringFromIndex:lastRange.location+1]];        //创建operation    DownLoadOperation *operation = [DownLoadOperation operationUrlWithString:urlString                                                                      params:nil httpMethod:@"GET" tempFilePath:temfilePath downloadFilePath:paramPath                                                                 rewriteFile:paramRewrite];    //判断文件是否下载    //创建一个BOOL值    BOOL exitsDownLoad = NO;    for (DownLoadOperation *op in self.allDownloads) {        if ([op.url isEqualToString:operation.url]) {            exitsDownLoad = YES;            NSLog(@"正在下载");        }    }    if (exitsDownLoad) {        [[self delegate] downloadEngineDownloadExist:self withURL:urlString];    }else if (operation == nil ){        [[self delegate] downloadEngineDownloadDone:self withURL:urlString];    }else    {        [self enqueueOperation:operation];//发起网络请求        [self.allDownloads addObject:operation];        //onDownloadProgressChanged:^(double progress)此方法为MKNetworkKit中的方法        //下载进度改变时回调方法downloadManager: withOperation: changeProgress:        [operation onDownloadProgressChanged:^(double progress) {            [[self delegate] changeprogress:progress withOperation:operation withEngine:self];        }];                //当任务完成都回调此方法.将下载在缓存中的文件移到指定的目录中存放        [operation onCompletion:^(MKNetworkOperation *completedOperation) {            NSFileManager *fileManager =[[NSFileManager alloc] init];            NSError *error = nil;            // 下载完成以后 先删除之前的文件 然后mv新的文件            //fileExistsAtPath判断paramFilePath是否存在,即是否下载完成            if ([fileManager fileExistsAtPath:paramPath]) {                [fileManager removeItemAtPath:paramPath error:&error];                if (error) {                    exit(-1);                }            }            //判断paramFilePath是否存在,若存在则将其移到tempFilePath文件中            [fileManager moveItemAtPath:temfilePath toPath:paramPath error:&error];            if (error) {                exit(-1);            }            //将operation从数组中移除            [[self delegate] downloadEngineDidFinsh:self withOperation:(DownLoadOperation *)completedOperation];            [self.allDownloads removeObject:operation];                                } onError:^(NSError *error) {            NSLog(@"出错了");        }];    }}//暂停下载- (void)cancelDownloadFileTaskInQueue:(NSString *)urlString{    DownLoadOperation *deleteOperation = nil;    for (DownLoadOperation *op in self.allDownloads) {        if ([op.url isEqualToString:urlString]) {            deleteOperation = op;        }    }    [[self delegate] downloadEnginePauseTask:self withURL:urlString];    [deleteOperation cancel];    [self.allDownloads removeObject:deleteOperation];}//暂停所有的下载'- (void)cancelAllOperations{    for (DownLoadOperation *op in self.allDownloads) {        [op cancel];    }    [self.allDownloads removeAllObjects];}

子类化的MKNetworkOperation:
.h文件
#import "MKNetworkOperation.h"@interface DownLoadOperation : MKNetworkOperation{        NSString *tempFilePath;    NSString *downloadFilePath;}//tempFilePath:(NSString *)tempFilePath下载文件时存放缓存路径//downloadFilePath:(NSString *)downloadFilePath文件完后存放的路径+(DownLoadOperation *)operationUrlWithString:(NSString *)urlString                                      params:(NSMutableDictionary *)params                                  httpMethod:(NSString *)method                                tempFilePath:(NSString *)tempFilePath                            downloadFilePath:(NSString *)downloadFilePath                                 rewriteFile:(BOOL)rewrite;

.m文件
+(DownLoadOperation *)operationUrlWithString:(NSString *)urlString                                      params:(NSMutableDictionary *)params                                  httpMethod:(NSString *)method                                tempFilePath:(NSString *)tempFilePath                            downloadFilePath:(NSString *)downloadFilePath                                 rewriteFile:(BOOL)rewrite{    //获得缓存的路径    // 创建文件管理器    NSFileManager *fileMgr = [NSFileManager defaultManager];    //初始化消息头    NSMutableDictionary *headersDic = [[NSMutableDictionary alloc] init];    //下载文件时或重新下载时    //首先判断缓存中是否有下载中的文件,如果有删除,没有则到文件下载完成后存放的路径中查看是否有下载好的文件,若有将其删除    //断点续传的关键在于rewriteFile:(BOOL)rewrite这个BOOL值..    if (rewrite &&[fileMgr fileExistsAtPath:tempFilePath]) {//        NSError *error = nil;//        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"文件已经存在是否继续下载" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:@"取消", nil];//        [alert show];        [fileMgr removeItemAtPath:tempFilePath error:nil];    }else if (rewrite &&[fileMgr fileExistsAtPath:downloadFilePath]){        NSError *error = nil;        [fileMgr removeItemAtPath:downloadFilePath error:&error];    }        //判断文件是否下载    //若没有下载则下载文件.并构建下载进度.下载中则返回空    if ([fileMgr fileExistsAtPath:downloadFilePath]) {        return nil;    }else {//[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleNameKey]是获得该工程下载文件的//[[[NSBundle mainBundle] infoDictionary]objectForKey:(NSString *)kCFBundleVersionKey]]获得版本号        NSString *userAgentString = [NSString stringWithFormat:@"%@/%@",                                     [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)                                         kCFBundleNameKey],                                     [[[NSBundle mainBundle] infoDictionary]objectForKey:(NSString *)kCFBundleVersionKey]];        [headersDic setObject:userAgentString forKey:@"momo"];                //判断之前是否下载 若下载则重新构造header(消息头)        if ([fileMgr fileExistsAtPath:tempFilePath]) {                    NSError *error = nil;            //通过计算大小可以算出下载到那里暂停的,继续下载时会从之前暂停的地方继续下载        unsigned long long fileSize = [[fileMgr attributesOfItemAtPath:tempFilePath error:&error]fileSize];        if (error) {            NSLog(@"get %@ fileSize failed!\nError:%@", tempFilePath, error);        }        NSString *headerRange = [NSString stringWithFormat:@"bytes=%llu-", fileSize];            [headersDic setObject:headerRange forKey:@"range"];        }                //初始化opertion(DownLoadOperation)        DownLoadOperation *opertion = [[DownLoadOperation alloc]                                       initWithURLString:urlString                                                  params:params                                              httpMethod:method];        [opertion addDownloadStream:[NSOutputStream outputStreamToFileAtPath:tempFilePath append:YES]];//下载文件的流使用NSOutputStream可以将网络请求的资源回来的数据保存到本地文件        [opertion addHeaders:headersDic];        return opertion;    }        }



这里大家可以借鉴几篇比较好的博文:
http://www.cnblogs.com/scorpiozj/archive/2013/07/29/3222803.html
http://blog.csdn.net/wlnana17/article/details/39376857

0 0