对YTKNetwork的官方demo的一些补漏

简介: 对YTKNetwork的官方demo的一些补漏

摘要:

相信大家就算没有使用过YTKNetwork,也应该听过这个框架的大名。如果要看基本功能使用,请参照官方demo。

我会介绍一些基本项目使用实际场景,及上传功能,及遇到的坑.

我来谈谈我是如何使用YTKNetwork的。


首先我会去定义一个基类。

下面是类的.h头文件

只定义了一个initWithDict目的是为了拼接参数

如果你们copy过去用,需要把一些参数改成你们自己公司的.

说到网络请求, 最初我也是使用的自己封装的AFN

但是,思考来去还是觉得离散式网络请求,比较适合我这个项目.

一个网络请求,一个类.意味着我可以对每个网络请求都单独的处理逻辑,以及自定义缓存.


对于说好坏,如果没有使用过,是没有发言权的.既然github上Star有这么多.肯定是有它的道理的.那么我就来使用一番,把它融入到自己项目中.回头再来评论好与坏.


还有关于自定义 acceptableContentTypes

当然在YTKNework的Issues 里面唐巧也回复了,需要KVC强行赋值,这个属性没有开放出来.

YTKNetworkAgent *agent = [YTKNetworkAgent sharedAgent];
    [agent setValue:[NSSet setWithObjects:@"application/json", @"text/plain", @"text/javascript", @"text/json",@"text/html",@"text/css", nil] forKeyPath:@"_manager.responseSerializer.acceptableContentTypes"];
//
//  MTRequest.h
//  LoveGuQin
//
//  Created by fox on 2018/5/30.
//  Copyright © 2018年 Moemoe. All rights reserved.
//
#import "YTKRequest.h"
#import <YTKNetwork.h>
@interface MTRequest : YTKRequest
- (instancetype)initWithDict:(NSDictionary *)dict;
@end

这个是.m文件

重写baseurl

如果有多域名的情况下,则可以重写baseurl方法即可


requestArgument

重写这个方法,可以添加一些公共参数


如果要添加请求头

requestHeaderFieldValueDictionary

//
//  MTRequest.m
//  LoveGuQin
//
//  Created by fox on 2018/5/30.
//  Copyright © 2018年 Moemoe. All rights reserved.
//
#import "MTRequest.h"
#import "MTUserModel.h"
@interface MTRequest()<YTKRequestAccessory>
@end
@implementation MTRequest {
    NSDictionary *_dict;
}
- (instancetype)initWithDict:(NSDictionary *)dict {
    if (self = [super init]) {
        _dict = dict; 
    }
    return self;
}
- (NSString *)baseUrl {
    return @"http://test.moemoetech.com";
}
/**
 重写请求参数
 @return 请求参数
 */
-(id)requestArgument {
    //可以在这里检查参数是否有带Token
    //如果没有这里可以补一个token
//    MTLog(@"%@",_dict);
    return _dict;
}
/**
 按照需重写 默认就post
 @return post
 */
- (YTKRequestMethod)requestMethod {
    return YTKRequestMethodPOST;
}
/**
 如果要添加请求头,可以实现这个方法
 @return nullable = 表示可以为null
 */
- (nullable NSDictionary<NSString *, NSString *> *)requestHeaderFieldValueDictionary {
    if ([MTUserModel shareUserModel].token.length > 0 ) {
      NSString *token = [NSString stringWithFormat:@"Bearer %@",[MTUserModel shareUserModel].token];
        return @{@"Authorization":token};
    }else {
         return nil;
    }
}
@end

如何使用呢?,去看官方文档吧,看这里也行.

这个是我加载数据的方法,只要一进来控制器,数据就会华丽丽的出来了,注意MTMainPersonalRequest 是继承自MTRequest的
- (void)moeupData {
    MTMainPersonalRequest *request = [[MTMainPersonalRequest alloc]init];
    request.delegate = self;
    [request start];
}
/// 请求完成
- (void)requestFinished:(__kindof YTKBaseRequest *)request {
    MTMainPersonalModel *model = [MTMainPersonalModel yy_modelWithDictionary:request.responseJSONObject];
    if ([model.code integerValue] == 1) {
        _model = model;
        MTLog(@"%@",_model.data.avatar);
        [self.tableView reloadData];
    }else {
        [MBProgressHUD MT_ShowError:model.message];
    }
}
/// 失败的回调
- (void)requestFailed:(__kindof YTKBaseRequest *)request {
    NSString  *error = request.error.localizedDescription;
    [MBProgressHUD MT_ShowError:error];
}

接下里是YTKNetwork的上传功能

这里演示一个上传图片

这个是.h

//
//  MTPersonalEditRequest.h
//  LoveGuQin
//
//  Created by fox on 14/06/2018.
//  Copyright © 2018 Moemoe. All rights reserved.
//
#import "MTRequest.h"
@interface MTPersonalEditRequest : YTKRequest
- (instancetype)initImage:(UIImage *)image;
@end

这个是.m

//
//  MTPersonalEditRequest.m
//  LoveGuQin
//
//  Created by fox on 14/06/2018.
//  Copyright © 2018 Moemoe. All rights reserved.
//
#import "MTPersonalEditRequest.h"
#import "AFNetWorking.h"
#import "MTUserModel.h"
@implementation MTPersonalEditRequest {
    UIImage *_image;
}
- (NSString *)requestUrl {
    return @"/api/uploadAva";
}
- (instancetype)initImage:(UIImage *)image {
    if (self = [super init]) {
        _image = image;
    }
    return self;
}
- (NSString *)baseUrl {
    return @"http://test.moemoetech.com";
}
- (BOOL)statusCodeValidator {
    return YES;
}
/**
 如果要添加请求头,可以实现这个方法
 @return nullable = 表示可以为null
 */
- (nullable NSDictionary<NSString *, NSString *> *)requestHeaderFieldValueDictionary {
    if ([MTUserModel shareUserModel].token.length > 0 ) {
        NSString *token = [NSString stringWithFormat:@"Bearer %@",[MTUserModel shareUserModel].token];
        return @{@"Authorization":token};
    }else {
        return nil;
    }
}
///上传必须得显示这个block
- (AFConstructingBlock)constructingBodyBlock {
    return ^(id<AFMultipartFormData> formData) {
         ///第一步:把图片转换成为禁止
        NSData *data = UIImageJPEGRepresentation(_image, 0.9);
        //拼接时间戳的目的就是为了文件名不重复
        NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];
        NSTimeInterval a=[date timeIntervalSince1970]; // *1000 是精确到毫秒,不乘就是精确到秒
        NSString *timeString = [NSString stringWithFormat:@"%.0f", a]; //转为字符型
      //这个是图片的名字
        NSString *name = [NSString stringWithFormat:@"%@.png",timeString];
      //formKey 这个字段老重要了,这个字段是后台给的.问后台要,如果字段错了,请求会报错.
        NSString *formKey = @"file";
     // 这里是告诉后台,你传递的图片有哪几种类型
        NSString *type = @"png/jpeg/jpg";
        [formData appendPartWithFileData:data name:formKey fileName:name mimeType:type];
    };      
}
- (YTKRequestMethod)requestMethod {
    return YTKRequestMethodPOST;
}
@end

回到控制器看看是如何使用的

#pragma mark - 点击了保存按钮
- (void)save {
    [self hudActionWithUploadingWithString:@"上 传 中"];
    MTPersonalEditRequest *request = [[MTPersonalEditRequest alloc]initImage:self.image];
    request.delegate = self;
    [request start];
}
- (void)requestFinished:(__kindof YTKBaseRequest *)request {
    NSDictionary *dict = request.responseJSONObject;
    MTLog(@"%@",request.responseJSONObject);
    if ([dict[@"code"]integerValue] == 1) {
        _model.data.avatar = dict[@"data"];
    NSDictionary *userDict = [self dicFromObject:_model.data];
    MTPersonalEditUploadRequest *request = [[MTPersonalEditUploadRequest alloc]initWithDict:userDict];
    [request startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest * _Nonnull request) {
        //请求成功
        //需要把头像跟用户名替换掉
        [self.mtHUD hide:YES];
         sleep(0.5);
         __weak __typeof(self) weakSelf  = self;
        [self hudActionWithSuccessWith:@"上传成功" AfterDelay:2 successBlock:^{
            self.callBackBlock(_model.data);
            [weakSelf mtPopback];
        }];
    } failure:^(__kindof YTKBaseRequest * _Nonnull request) {
        [self.mtHUD hide:YES];
        [self hudActionWithFailWithaftAerDelay:2.0 withErrorStr:@"上传失败"];
    }];
    }
}
- (void)requestFailed:(__kindof YTKBaseRequest *)request {
    [self.mtHUD hide:YES];
    [self hudActionWithFailWithaftAerDelay:2.0 withErrorStr:@"上传失败"];
}

上面看完了上传,再给你们来一个图片上传

老规矩还是看.h个跟.m

//
//  MTExerciseEditUploadRequest.h
//  LoveGuQin
//
//  Created by fox on 2018/6/24.
//  Copyright © 2018年 Moemoe. All rights reserved.
//
#import "MTRequest.h"
@interface MTExerciseEditUploadRequest : MTRequest
- (instancetype)initWithDict:(NSDictionary *)dict;
@end

在看看.m

//
//  MTExerciseEditUploadRequest.m
//  LoveGuQin
//
//  Created by fox on 2018/6/24.
//  Copyright © 2018年 Moemoe. All rights reserved.
//
#import "MTExerciseEditUploadRequest.h"
#import "AFNetWorking.h"
#import "MTUserModel.h"
@implementation MTExerciseEditUploadRequest {
    NSDictionary *_dict;
}
- (NSString *)requestUrl {
    return @"/api/exercise/edit";
}
- (instancetype)initWithDict:(NSDictionary *)dict{
    if (self = [super init]) {
        _dict = dict;
    }
    return self;
}
/**
 重写请求参数
 @return 请求参数
 */
-(id)requestArgument {
    //可以在这里检查参数是否有带Token
    //如果没有这里可以补一个token
    //    MTLog(@"%@",_dict);
    return _dict;
}
- (BOOL)statusCodeValidator {
    return YES;
}
/**
 如果要添加请求头,可以实现这个方法
 @return nullable = 表示可以为null
 */
- (nullable NSDictionary<NSString *, NSString *> *)requestHeaderFieldValueDictionary {
    if ([MTUserModel shareUserModel].token.length > 0 ) {
        NSString *token = [NSString stringWithFormat:@"Bearer %@",[MTUserModel shareUserModel].token];
        return @{@"Authorization":token};
    }else {
        return nil;
    }
}
//依旧实现这个block跟上传图片其实一样一样的.重点是,可以带参数.最终发现,initWithDict带的参数会把它拼接在body中
- (AFConstructingBlock)constructingBodyBlock {
    return ^(id<AFMultipartFormData> formData) {
        NSData *data;
    if ([[NSFileManager defaultManager]fileExistsAtPath:_dict[@"urlString"]]) {
        data = [[NSFileManager defaultManager]contentsAtPath:_dict[@"urlString"]];
        if (data.length > 0) {
       CGFloat size =  [[[NSFileManager defaultManager] attributesOfItemAtPath:_dict[@"urlString"] error:nil] fileSize]/(1024.0*1024);
            MTLog(@"文件大小 %f",size);
        }
    }
        NSString *name = _dict[@"file_id"];
        NSString *formKey = @"file";
        NSString *type = @"mp4/aac";
        MTLog(@"%@",name);
        [formData appendPartWithFileData:data name:formKey fileName:name mimeType:type];
//        [formData appendPartWithHeaders:_dict body:data];
    };
}
- (YTKRequestMethod)requestMethod {
    return YTKRequestMethodPOST;
}
@end

好了,以上这些有一些跟YTKNetwork的demo有些重合,

但是我依旧认为官方demo里给的上传的样例太少了.实际上,官方给的根本跑不通,不够全面.


相关文章
|
Swift iOS开发 Perl
如何解决Swift混编的module编译错误
前言很多iOS工程都是基于Object-C开发,再逐步向Swift演进,演进过程中不可避免要进行Swift混编。Swift模块需要支持LLVM Module规范,混编工程会遇到各种Module编译错误。这对于不熟悉的同学来说简直是灾难,严重影响开发效率。本文会介绍常见的Module编译错误,希望对大家有所帮助。常见错误1:Could not build module xxx当一个OC模块引用了Sw
7545 1
如何解决Swift混编的module编译错误
|
4月前
|
API 开发工具 Android开发
【HarmonyOS 5】鸿蒙中进度条的使用详解
【HarmonyOS 5】鸿蒙中进度条的使用详解
241 7
|
Swift Perl
OC和swift混合工程更新库时报:target has transitive dependencies that include statically linked binaries
OC和swift混合工程更新库时报:target has transitive dependencies that include statically linked binaries
427 0
|
机器学习/深度学习 人工智能 自然语言处理
深度学习还不如浅层网络?RL教父Sutton持续反向传播算法登Nature
【9月更文挑战第24天】近年来,深度学习在人工智能领域取得巨大成功,但在连续学习任务中面临“损失可塑性”问题,尤其在深度强化学习中更为突出。加拿大阿尔伯塔大学的研究人员提出了一种名为“持续反向传播”的算法,通过选择性地重新初始化网络中的低效用单元,保持模型的可塑性。该算法通过评估每个连接和权重的贡献效用来决定是否重新初始化隐藏单元,并引入成熟度阈值保护新单元。实验表明,该算法能显著提升连续学习任务的表现,尤其在深度强化学习领域效果明显。然而,算法也存在计算复杂性和成熟度阈值设置等问题。
225 2
|
存储 监控 数据库
大师学SwiftUI第18章Part2 - 存储图片和自定义相机
在前面的示例中,我们在屏幕上展示了图片,但也可以将其存储到文件或数据库中。另外有时使用相机将照片存储到设备的相册薄里会很有用,这样可供其它应用访问。UIKit框架提供了如下两个保存图片和视频的函数。 •
609 0
|
算法 Linux Windows
Linux|如何查找和删除重复文件
Linux|如何查找和删除重复文件
|
XML Java API
List与String相互转化的方法有哪些
摘要:本文概述了Java中List转换为String及反之的多种策略。使用`String.join()`可简洁地连接List元素;`StringBuilder`提供灵活控制;Java 8 Stream API收集器简化操作;Apache Commons Lang3的`StringUtils.join()`和Guava的`Joiner.on()`支持外部库的高效转换。
536 2
|
负载均衡 jenkins 应用服务中间件
大规模部署下的 Jenkins 高可用性与负载均衡
【8月更文第31天】随着软件开发流程的加速,持续集成/持续交付(CI/CD)工具的重要性日益凸显。Jenkins 作为最受欢迎的 CI/CD 平台之一,为企业提供了强大的自动化构建和部署功能。然而,在大规模部署场景下,单一的 Jenkins 实例可能无法满足高可用性和性能的需求。本文将探讨如何设计和实施 Jenkins 高可用集群,以支持大型组织的需求,并通过负载均衡技术来提高系统的稳定性和响应速度。
766 0
|
JSON 算法 数据可视化
Open3d-Point cloud (点云)
Open3d-Point cloud (点云)
1157 6
|
开发工具 Windows
搭建 Qt 开发环境
搭建 Qt 开发环境