IOS中json字符串原生数据请求&IOS跨平台AES128字符串加解密&AFNetworking框架的简单封装使用
2016-07-15 19:57
761 查看
@废话在前
IOS开发中原始的数据请求是以字符串的形式,字符串参数传到服务器,然后接收服务器返回的字符串进行解析。
通常一个完整的数据请求过程中数据处理经如下几个阶段:
1.制作参数,用NSDictionary封装,即一个son对象;
2.json对象转成json字符串;
3.字符串加密成密文(可选);
4.将json字符串(或加密后的密文)作为参数发送请求;
5.接受服务器返回的数据NSData,并转成字符串;
6.字符串解密(可选);
7.json字符串转json对象(NSDictionary);
一.IOS原生数据请求与数据解析
这里建立一个IOS原生session回话任务封装一个post请求(post请求更安全常用):
使用方法是将上面的类加入工程,然后调用单例类的类函数即可:
二.AES128加解密(解决ios与服务器等其他平台加密密文尾巴不一致的问题)
加密解密的函数封装在下面的工具类中(其中用到了谷歌的GTMBase64编码工具类可网上自行下载):
三.AFNetworking网络请求框架的使用
AFNetworking框架基础介绍:http://blog.csdn.net/cordova/article/details/51614695
未完待续... ...
IOS开发中原始的数据请求是以字符串的形式,字符串参数传到服务器,然后接收服务器返回的字符串进行解析。
通常一个完整的数据请求过程中数据处理经如下几个阶段:
1.制作参数,用NSDictionary封装,即一个son对象;
2.json对象转成json字符串;
3.字符串加密成密文(可选);
4.将json字符串(或加密后的密文)作为参数发送请求;
5.接受服务器返回的数据NSData,并转成字符串;
6.字符串解密(可选);
7.json字符串转json对象(NSDictionary);
一.IOS原生数据请求与数据解析
这里建立一个IOS原生session回话任务封装一个post请求(post请求更安全常用):
// // RequestSingleton.h // JXHDemo // // Created by Xinhou Jiang on 6/12/16. // Copyright © 2016 Jiangxh. All rights reserved. // #import <Foundation/Foundation.h> @interface RequestSingleton : NSObject /** * 获取QueuesSingleton单例对象 */ + (RequestSingleton *)Ins; /** * 原生POST请求(最基础的请求参数是字符串,这里原生的请求参数是一个json字符串) */ - (void) POST: (NSString *)url param: (NSString *)param success:(void(^)(id json))success failure: (void(^)(NSError *error))flaiure; @end
// // RequestSingleton.m // JXHDemo // // Created by Xinhou Jiang on 6/12/16. // Copyright © 2016 Jiangxh. All rights reserved. // #import "RequestSingleton.h" @interface RequestSingleton() /** * session,创建一个共用的即可 */ @property(nonatomic, strong)NSURLSession *session; @end @implementation RequestSingleton /** * 获取单例对象 */ + (RequestSingleton *)Ins { static dispatch_once_t once; static id sharedInstance; dispatch_once(&once, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; } /** * init */ - (id)init { if (self = [super init]) { // 通用session _session = [NSURLSession sharedSession]; } return self; } /** * 原生POST请求, 客可对此进一步封装,进行参数的拼接,加密等等 */ - (void)POST:(NSString *)url param:(NSString *)param success:(void (^)(id json))success failure:(void (^)(NSError *))flaiure { // url对象 NSURL *URL = [NSURL URLWithString:url]; // request NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; // post请求 request.HTTPMethod = @"POST"; // 参数 request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding]; // 请求超时 request.timeoutInterval = 30; //根据会话对象创建一个发送请求Task NSURLSessionDataTask *dataTask = [_session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 解析数据, 将NSData转成json对象 id json = [self decrypeJsonWithData:data]; // 如果error为nil说明没有网络错误,请求成功 if (!error) { // 将数据上抛传出去 success(json); // 打印 NSLog(@"返回数据:%@",json); }else { // 网络错误,请求失败,包括请求超时等等 flaiure(error); } }]; //执行任务 [dataTask resume]; } /** * NSData转JSON对象 */ - (id)decrypeJsonWithData:(NSData *)data { // 1. 转成字符串 NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; // 2. 解密 // 如果是加密传输在这里进行解密 // 3. 转成json对象 return [NSJSONSerialization JSONObjectWithData:[jsonStr dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil]; } @end
使用方法是将上面的类加入工程,然后调用单例类的类函数即可:
#import "RequestSingleton.h"
/** * 原生网络请求测试示例 */ - (void)request { // 1.服务器url接口 NSString *url = @""; // 2.制作参数 NSMutableDictionary *paramDic = [[NSMutableDictionary alloc]init]; [paramDic setObject:@"919575700@qq.com" forKey:@"username"]; [paramDic setObject:@"jxh123" forKey:@"password"]; // 转成json字符串,用到MJExtension归档插件 NSString *param = [paramDic JSONString]; // post请求 [[RequestSingleton Ins] POST:url param:param success:^(id json) { // 请求成功 } failure:^(NSError *error) { // 请求错误 }]; }
二.AES128加解密(解决ios与服务器等其他平台加密密文尾巴不一致的问题)
加密解密的函数封装在下面的工具类中(其中用到了谷歌的GTMBase64编码工具类可网上自行下载):
#import <Foundation/Foundation.h> @interface DES3Util : NSObject // 加密 + (NSString*) AES128Encrypt:(NSString *)plainText; // 解密 + (NSString*) AES128Decrypt:(NSString *)encryptText; @end
#import "DES3Util.h" #import <CommonCrypto/CommonCryptor.h> #import "GTMBase64.h" @implementation DES3Util // 加密 +(NSString *)AES128Encrypt:(NSString *)plainText { char keyPtr[kCCKeySizeAES128+1]; memset(keyPtr, 0, sizeof(keyPtr)); [AES128Key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128+1]; memset(ivPtr, 0, sizeof(ivPtr)); [AES128Iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding]; NSUInteger dataLength = [data length]; int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128); int newSize = 0; if(diff > 0) { newSize = (int)dataLength + diff; } char dataPtr[newSize]; memcpy(dataPtr, [data bytes], [data length]); for(int i = 0; i < diff; i++) { dataPtr[i + dataLength] = 0x00; } size_t bufferSize = newSize + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); memset(buffer, 0, bufferSize); size_t numBytesCrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, 0x0000, //No padding keyPtr, kCCKeySizeAES128, ivPtr, dataPtr, sizeof(dataPtr), buffer, bufferSize, &numBytesCrypted); if (cryptStatus == kCCSuccess) { NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted]; return [GTMBase64 stringByEncodingData:resultData]; } free(buffer); return nil; } // 解密 +(NSString *)AES128Decrypt:(NSString *)encryptText { char keyPtr[kCCKeySizeAES128 + 1]; memset(keyPtr, 0, sizeof(keyPtr)); [AES128Key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128 + 1]; memset(ivPtr, 0, sizeof(ivPtr)); [AES128Iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; NSData *data = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]]; NSUInteger dataLength = [data length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesCrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 0x0000, keyPtr, kCCBlockSizeAES128, ivPtr, [data bytes], dataLength, buffer, bufferSize, &numBytesCrypted); if (cryptStatus == kCCSuccess) { NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted]; return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding]; } free(buffer); return nil; } @end实际应用中会发现上面的加解密方法在ios本地没有问题,但和服务器加密的密文尾巴不一致,导致服务器无法解析,需要对密文进行特殊字符的处理,在发送请求前将加密的参数密文经过下面的函数处理一下即可:
/** * aes128加密后的密文编码处理,参数为128加密后的密文 */ - (NSString *)AES128Convert: (NSString *)aes128 { NSString *charactersToEscape = @"!*'();:@&=+$,/?%#[]\" "; NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet]; return [aes128 stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters]; }
三.AFNetworking网络请求框架的使用
AFNetworking框架基础介绍:http://blog.csdn.net/cordova/article/details/51614695
未完待续... ...
相关文章推荐
- ios开发——日常之XCode 文件后面带有问号的问题怎么解决??
- 【iOS】Xcode 插件安装后无效
- iOS/mac开发的一些知名个人博客
- IOS NSDictionary 、 NSData 相互转换
- IOS 中视频和音乐合成
- IOS 中视频和音乐合成
- KVC解析
- 播放本地音频
- 常用的异步线程
- iOS addChildViewController 使用
- 关于iOS硬解码的一些感悟
- IOS开发广告接入iAD框架_InMobi框架
- 判断字符串是否为空
- iOS10本地通知的探索
- iOS获取运营商的相关信息
- iOS后台模式BackgroundMode
- iOS开发-Xcode Debug、Release、Archive、Profile、Analyze概念解释
- iOS - 遍历指定路径下的所有文件(不包括更下级文件)
- 最近这么火的iOS视频直播
- iOS中全局悬浮按钮,类似IPhone中的AssistiveTouch