CNLiveURLRequestSerialization.m
4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// CNLiveUserURLRequestSerialization.m
// CNLiveHttpRequestDemo
//
// Created by Android on 16/7/26.
// Copyright © 2016年 Android. All rights reserved.
//
#import "CNLiveURLRequestSerialization.h"
@interface CNLiveUserURLRequestSerialization ()
@property (readwrite, nonatomic, strong) id value;
@property (readwrite, nonatomic, strong) id field;
@end
@implementation CNLiveUserURLRequestSerialization
- (id)initWithField:(id)field value:(id)value
{
self = [super init];
if (self) {
self.field = field;
self.value = value;
}
return self;
}
#pragma mark -
FOUNDATION_EXPORT NSArray * CNUserQueryStringPairsFromDictionary(NSDictionary *dictionary);
FOUNDATION_EXPORT NSArray * CNUserQueryStringPairsFromKeyAndValue(NSString *key, id value);
+ (NSString *)CNUserQueryStringFromParameters:(NSDictionary *)parameters
{
NSMutableArray *mutablePairs = [NSMutableArray array];
for (CNLiveUserURLRequestSerialization *pair in CNUserQueryStringPairsFromDictionary(parameters)) {
[mutablePairs addObject:[pair URLEncodedStringValue]];
}
return [mutablePairs componentsJoinedByString:@"&"];
}
NSArray * CNUserQueryStringPairsFromDictionary(NSDictionary *dictionary)
{
return CNUserQueryStringPairsFromKeyAndValue(nil, dictionary);
}
/**
* 处理上传参数
*/
NSArray * CNUserQueryStringPairsFromKeyAndValue(NSString *key, id value)
{
NSMutableArray *mutableQueryStringComponents = [NSMutableArray array];
//排序方式
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES selector:@selector(compare:)];
if ([value isKindOfClass:[NSDictionary class]]) { //字典
NSDictionary *dictionary = value;
for (id nestedKey in [dictionary.allKeys sortedArrayUsingDescriptors:@[sortDescriptor]]) {
id nestedValue = dictionary[nestedKey];
if (nestedKey) {
[mutableQueryStringComponents addObjectsFromArray:CNUserQueryStringPairsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)];
}
}
}
else if ([value isKindOfClass:[NSArray class]]){ //数组
NSArray *array = value;
for (id nestedValue in array) {
[mutableQueryStringComponents addObjectsFromArray:CNUserQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)];
}
}else if ([value isKindOfClass:[NSSet class]]){ //集合
NSSet *set = value;
for (id obj in [set sortedArrayUsingDescriptors:@[ sortDescriptor ]]) {
[mutableQueryStringComponents addObjectsFromArray:CNUserQueryStringPairsFromKeyAndValue(key, obj)];
}
}else{ //其他类型
[mutableQueryStringComponents addObject:[[CNLiveUserURLRequestSerialization alloc] initWithField:key value:value]];
}
return mutableQueryStringComponents;
}
static NSString * CNPercentEscapedStringFromString(NSString *string) {
static NSString * const kCNCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
static NSString * const kCNCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[allowedCharacterSet removeCharactersInString:[kCNCharactersGeneralDelimitersToEncode stringByAppendingString:kCNCharactersSubDelimitersToEncode]];
static NSUInteger const batchSize = 50;
NSUInteger index = 0;
NSMutableString *escaped = @"".mutableCopy;
while (index < string.length) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wgnu"
NSUInteger length = MIN(string.length - index, batchSize);
#pragma GCC diagnostic pop
NSRange range = NSMakeRange(index, length);
range = [string rangeOfComposedCharacterSequencesForRange:range];
NSString *substring = [string substringWithRange:range];
NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
[escaped appendString:encoded];
index += range.length;
}
return escaped;
}
- (NSString *)URLEncodedStringValue {
if (!self.value || [self.value isEqual:[NSNull null]]) {
return CNPercentEscapedStringFromString([self.field description]);
} else {
return [NSString stringWithFormat:@"%@=%@", CNPercentEscapedStringFromString([self.field description]), CNPercentEscapedStringFromString([self.value description])];
}
}
@end