Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
coderZsq committed Nov 22, 2020
1 parent 5b658b8 commit 427ae7b
Show file tree
Hide file tree
Showing 9 changed files with 558 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 51;
objects = {

/* Begin PBXBuildFile section */
Expand All @@ -14,6 +14,8 @@
14A334922568D62500772436 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 14A334912568D62500772436 /* Assets.xcassets */; };
14A334952568D62500772436 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14A334932568D62500772436 /* LaunchScreen.storyboard */; };
14A334982568D62500772436 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 14A334972568D62500772436 /* main.m */; };
14ED0256256A480700D370FD /* SQQueryStringPair.m in Sources */ = {isa = PBXBuildFile; fileRef = 14ED0255256A480700D370FD /* SQQueryStringPair.m */; };
14ED0267256A4AD700D370FD /* SQURLRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 14ED0266256A4AD700D370FD /* SQURLRequestSerialization.m */; };
1E4C433D320B90193A1EE719 /* Pods_AFNetworking_Debug.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E27C56A0FCB7F71F556F4D1 /* Pods_AFNetworking_Debug.framework */; };
/* End PBXBuildFile section */

Expand All @@ -31,6 +33,10 @@
14A334942568D62500772436 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
14A334962568D62500772436 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
14A334972568D62500772436 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
14ED0254256A480700D370FD /* SQQueryStringPair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQQueryStringPair.h; sourceTree = "<group>"; };
14ED0255256A480700D370FD /* SQQueryStringPair.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SQQueryStringPair.m; sourceTree = "<group>"; };
14ED0265256A4AD700D370FD /* SQURLRequestSerialization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQURLRequestSerialization.h; sourceTree = "<group>"; };
14ED0266256A4AD700D370FD /* SQURLRequestSerialization.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SQURLRequestSerialization.m; sourceTree = "<group>"; };
3E27C56A0FCB7F71F556F4D1 /* Pods_AFNetworking_Debug.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AFNetworking_Debug.framework; sourceTree = BUILT_PRODUCTS_DIR; };
67E409C126A533A0A2F1DA57 /* Pods-AFNetworking-Debug.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AFNetworking-Debug.debug.xcconfig"; path = "Target Support Files/Pods-AFNetworking-Debug/Pods-AFNetworking-Debug.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -74,6 +80,10 @@
14A334892568D62400772436 /* SceneDelegate.m */,
14A3348B2568D62400772436 /* ViewController.h */,
14A3348C2568D62400772436 /* ViewController.m */,
14ED0254256A480700D370FD /* SQQueryStringPair.h */,
14ED0255256A480700D370FD /* SQQueryStringPair.m */,
14ED0265256A4AD700D370FD /* SQURLRequestSerialization.h */,
14ED0266256A4AD700D370FD /* SQURLRequestSerialization.m */,
14A3348E2568D62400772436 /* Main.storyboard */,
14A334912568D62500772436 /* Assets.xcassets */,
14A334932568D62500772436 /* LaunchScreen.storyboard */,
Expand All @@ -97,7 +107,6 @@
67E409C126A533A0A2F1DA57 /* Pods-AFNetworking-Debug.debug.xcconfig */,
002F3802D60E85956ACBBB58 /* Pods-AFNetworking-Debug.release.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
Expand Down Expand Up @@ -216,8 +225,10 @@
files = (
14A3348D2568D62400772436 /* ViewController.m in Sources */,
14A334872568D62400772436 /* AppDelegate.m in Sources */,
14ED0267256A4AD700D370FD /* SQURLRequestSerialization.m in Sources */,
14A334982568D62500772436 /* main.m in Sources */,
14A3348A2568D62400772436 /* SceneDelegate.m in Sources */,
14ED0256256A480700D370FD /* SQQueryStringPair.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// SQQueryStringPair.h
// AFNetworking-Debug
//
// Created by 朱双泉 on 2020/11/22.
//

#import <Foundation/Foundation.h>

@interface SQQueryStringPair : NSObject

@property (readwrite, nonatomic, strong) id field;
@property (readwrite, nonatomic, strong) id value;

- (instancetype)initWithField:(id)field value:(id)value;

- (NSString *)URLEncodedStringValue;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// SQQueryStringPair.m
// AFNetworking-Debug
//
// Created by 朱双泉 on 2020/11/22.
//

#import "SQQueryStringPair.h"

@implementation SQQueryStringPair

NSString * SQPercentEscapedStringFromString(NSString *string) {
// return string;
static NSString * const kSQCharactersGeneralDelimitersToEncode = @":#[]@";
static NSString * const kSQCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[allowedCharacterSet removeCharactersInString:[kSQCharactersGeneralDelimitersToEncode stringByAppendingString:kSQCharactersSubDelimitersToEncode]];
NSString *encoded = [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];

static NSUInteger const batchSize = 50;
NSUInteger index = 0;
NSMutableString *escaped = @"".mutableCopy;
while (index < string.length) {
NSUInteger length = MIN(string.length - index, batchSize);
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 encoded;
}

- (instancetype)initWithField:(id)field value:(id)value {
self = [super init];
if (!self) {
return nil;
}

self.field = field;
self.value = value;

return self;
}

- (NSString *)URLEncodedStringValue {
if (!self.value || [self.value isEqual:[NSNull null]]) {
return SQPercentEscapedStringFromString([self.field description]);
} else {
return [NSString stringWithFormat:@"%@=%@", SQPercentEscapedStringFromString([self.field description]), SQPercentEscapedStringFromString([self.value description])];
}
}

- (NSString *)description {
return [self URLEncodedStringValue];
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// SQURLRequestSerialization.h
// AFNetworking-Debug
//
// Created by 朱双泉 on 2020/11/22.
//

#import <Foundation/Foundation.h>

@interface SQURLRequestSerialization : NSObject

NSString * SQQueryStringFromParameters(NSDictionary *parameters);

NSArray * SQQueryStringPairFromDictionary(NSDictionary *dictionary);

NSArray * SQQueryStringPairsFromKeyAndValue(NSString *key, id value);

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// SQURLRequestSerialization.m
// AFNetworking-Debug
//
// Created by 朱双泉 on 2020/11/22.
//

#import "SQURLRequestSerialization.h"
#import "SQQueryStringPair.h"

@implementation SQURLRequestSerialization

NSString * SQQueryStringFromParameters(NSDictionary *parameters) {
NSMutableArray *mutablePairs = [NSMutableArray array];
for (SQQueryStringPair *pair in SQQueryStringPairFromDictionary(parameters)) {
[mutablePairs addObject:[pair URLEncodedStringValue]];
}
return [mutablePairs componentsJoinedByString:@"&"];
}

NSArray * SQQueryStringPairFromDictionary(NSDictionary *dictionary) {
return SQQueryStringPairsFromKeyAndValue(nil, dictionary);
}

NSArray * SQQueryStringPairsFromKeyAndValue(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 (nestedValue) {
[mutableQueryStringComponents addObjectsFromArray:SQQueryStringPairsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)];
}
}
} else if ([value isKindOfClass:[NSArray class]]) {
NSArray *array = value;
for (id nestedValue in array) {
[mutableQueryStringComponents addObjectsFromArray:SQQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)];
}
} else if ([value isKindOfClass:[NSSet class]]) {
NSSet *set = value;
for (id obj in [set sortedArrayUsingDescriptors:@[ sortDescriptor ]]) {
[mutableQueryStringComponents addObjectsFromArray:SQQueryStringPairsFromKeyAndValue(key, obj)];
}
} else {
[mutableQueryStringComponents addObject:[[SQQueryStringPair alloc] initWithField:key value:value]];
}
return mutableQueryStringComponents;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#import "ViewController.h"
#import <AFNetworking.h>
#import "SQQueryStringPair.h"
#import "SQURLRequestSerialization.h"

@interface ViewController ()
@property (nonatomic, weak) IBOutlet UIProgressView *progressView;
Expand Down Expand Up @@ -173,6 +175,55 @@ - (void)debug_AFNURLRequestSerialSerialization {

NSLog(@"QueryString: %@", AFQueryStringFromParameters(@{@"a": @1, @"b": @2, @"c": @3}));
// QueryString: a=1&b=2&c=3

NSLog(@"AFURLRequestSerializationErrorDomain: %@", AFURLRequestSerializationErrorDomain);
// AFURLRequestSerializationErrorDomain: com.alamofire.error.serialization.request
NSLog(@"AFNetworkingOperationFailingURLRequestErrorKey: %@", AFNetworkingOperationFailingURLRequestErrorKey);
// AFNetworkingOperationFailingURLRequestErrorKey: com.alamofire.serialization.request.error.response
NSLog(@"kAFUploadStream3GSuggestedPacketSize: %lu", kAFUploadStream3GSuggestedPacketSize);
// kAFUploadStream3GSuggestedPacketSize: 16384
NSLog(@"kAFUploadStream3GSuggestedDelay: %f", kAFUploadStream3GSuggestedDelay);
// kAFUploadStream3GSuggestedDelay: 0.200000

SQQueryStringPair *pair = [[SQQueryStringPair alloc] initWithField:@"a" value:@1];
NSLog(@"%@", [pair URLEncodedStringValue]);
// a=1

SQQueryStringPair *pair2 = [[SQQueryStringPair alloc] initWithField:@"b" value:nil];
NSLog(@"%@", [pair2 URLEncodedStringValue]);
// b

NSLog(@"%@", SQQueryStringPairsFromKeyAndValue(@"a", @1));
/**
(
"a=1"
)
*/

NSLog(@"%@", SQQueryStringPairsFromKeyAndValue(@"a", @{@"b": @{@"c": @3}, @"d": @""}));
/**
(
"a[b][c]=3",
"a[d]="
)
*/
NSLog(@"%@", SQQueryStringPairsFromKeyAndValue(@"a", @[@"b", @{@"c": @3}, @"d"]));
/**
(
"a[]=b",
"a[][c]=3",
"a[]=d"
)
*/
NSLog(@"%@", SQQueryStringPairFromDictionary(@{@"a": @{@"b": @{@"c": @3}, @"d": @""}}));
/**
(
"a[b][c]=3",
"a[d]="
)
*/
NSLog(@"%@", SQQueryStringFromParameters(@{@"a": @{@"b": @{@"c": @3}, @"d": @""}}));
// a[b][c]=3&a[d]=
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -427,49 +427,49 @@ forHTTPHeaderField:(NSString *)field;
#pragma mark -

///----------------
/// @name Constants
/// @name 常数
///----------------

/**
## Error Domains
##错误域
The following error domain is predefined.
以下错误域是预定义的。
- `NSString * const AFURLRequestSerializationErrorDomain`
-`NSString * const AFURLRequestSerializationErrorDomain`
### Constants
###常数
`AFURLRequestSerializationErrorDomain`
AFURLRequestSerializer errors. Error codes for `AFURLRequestSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`.
AFURLRequestSerializationErrorDomain AFURLRequestSerializer错误。
AFURLRequestSerializationErrorDomain的错误代码对应于NSURLErrorDomain的代码。
*/
FOUNDATION_EXPORT NSString * const AFURLRequestSerializationErrorDomain;

/**
## User info dictionary keys
##用户信息字典键
These keys may exist in the user info dictionary, in addition to those defined for NSError.
除了为NSError定义的密钥外,这些密钥还可以存在于用户信息字典中。
- `NSString * const AFNetworkingOperationFailingURLRequestErrorKey`
-`NSString * const AFNetworkingOperationFailingURLRequestErrorKey`
### Constants
###常数
`AFNetworkingOperationFailingURLRequestErrorKey`
The corresponding value is an `NSURLRequest` containing the request of the operation associated with an error. This key is only present in the `AFURLRequestSerializationErrorDomain`.
AFNetworkingOperationFailingURLRequestErrorKey
相应的值为“ NSURLRequest”,其中包含与错误相关联的操作请求。 该密钥仅存在于“ AFURLRequestSerializationErrorDomain”中。
*/
FOUNDATION_EXPORT NSString * const AFNetworkingOperationFailingURLRequestErrorKey;

/**
## Throttling Bandwidth for HTTP Request Input Streams
## HTTP请求输入流的限制带宽
@see -throttleBandwidthWithPacketSize:delay:
@see -throttleBandwidthWithPacketSizedelay
### Constants
###常数
`kAFUploadStream3GSuggestedPacketSize`
Maximum packet size, in number of bytes. Equal to 16kb.
kAFUploadStream3GSuggestedPacketSize
最大数据包大小,以字节数为单位。 等于16kb。
`kAFUploadStream3GSuggestedDelay`
Duration of delay each time a packet is read. Equal to 0.2 seconds.
kAFUploadStream3GSuggestedDelay
每次读取数据包的延迟时间。 等于0.2秒。
*/
FOUNDATION_EXPORT NSUInteger const kAFUploadStream3GSuggestedPacketSize;
FOUNDATION_EXPORT NSTimeInterval const kAFUploadStream3GSuggestedDelay;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,17 @@
typedef NSString * (^AFQueryStringSerializationBlock)(NSURLRequest *request, id parameters, NSError *__autoreleasing *error);

/**
Returns a percent-escaped string following RFC 3986 for a query string key or value.
RFC 3986 states that the following characters are "reserved" characters.
- General Delimiters: ":", "#", "[", "]", "@", "?", "/"
- Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
should be percent-escaped in the query string.
- parameter string: The string to be percent-escaped.
- returns: The percent-escaped string.
返回遵循RFC 3986的查询字符串键或值的百分比转义字符串。
RFC 3986声明以下字符为“保留”字符。
-通用分隔符:“:”,“#”,“ [”,“]”,“ @”,“?”,“ /”
-子定界符:“!”,“ $”,“&”,“'”,“(”,“)”,“ *”,“ +”,“,”,“,”,“ =”
在RFC 3986-3.4节中,它指出“?” 和“ /”字符不应转义以允许查询字符串包含URL。 因此,所有“保留”字符(“?”除外) 和“ /”应该在查询字符串中转义。
-参数字符串:要百分号转义的字符串。
-返回:转义百分比的字符串。
*/
NSString * AFPercentEscapedStringFromString(NSString *string) {
static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // 不包括 ”?” 或“ /”(由于RFC 3986-第3.4节)
static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";

NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
Expand All @@ -63,7 +61,7 @@
NSUInteger length = MIN(string.length - index, batchSize);
NSRange range = NSMakeRange(index, length);

// To avoid breaking up character sequences such as 👴🏻👮🏽
//为了避免破坏诸如👴🏻👮🏽之类的字符序列
range = [string rangeOfComposedCharacterSequencesForRange:range];

NSString *substring = [string substringWithRange:range];
Expand Down Expand Up @@ -136,7 +134,7 @@ - (NSString *)URLEncodedStringValue {

if ([value isKindOfClass:[NSDictionary class]]) {
NSDictionary *dictionary = value;
// Sort dictionary keys to ensure consistent ordering in query string, which is important when deserializing potentially ambiguous sequences, such as an array of dictionaries
// 对字典键进行排序以确保查询字符串中的顺序一致,这在反序列化可能含糊的序列(例如字典数组)时很重要
for (id nestedKey in [dictionary.allKeys sortedArrayUsingDescriptors:@[ sortDescriptor ]]) {
id nestedValue = dictionary[nestedKey];
if (nestedValue) {
Expand Down
Loading

0 comments on commit 427ae7b

Please sign in to comment.