mirror of
https://github.com/silkimen/cordova-plugin-advanced-http.git
synced 2026-02-11 00:00:06 +08:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66b7a31bc6 | ||
|
|
83e903b409 | ||
|
|
5ed4dce809 | ||
|
|
872b5fa013 | ||
|
|
75296f0734 | ||
|
|
978708890b | ||
|
|
4fc676cc67 | ||
|
|
0b01dc8b69 | ||
|
|
0d67760abb | ||
|
|
5c138dc39f | ||
|
|
be660f97d8 | ||
|
|
e562bd0627 | ||
|
|
c5f5a33f07 | ||
|
|
7a20200f8e | ||
|
|
bd8207a390 | ||
|
|
e507759527 | ||
|
|
e83229e837 | ||
|
|
03dc55bdf9 | ||
|
|
7d67b295fa |
31
README.md
31
README.md
@@ -39,7 +39,7 @@ All available functions are documented below. Every function takes a success an
|
||||
### useBasicAuth
|
||||
This sets up all future requests to use Basic HTTP authentication with the given username and password.
|
||||
|
||||
cordovaHttp.useBasicAuth("user", "password", function() {
|
||||
cordovaHTTP.useBasicAuth("user", "password", function() {
|
||||
console.log('success!');
|
||||
}, function() {
|
||||
console.log('error :(');
|
||||
@@ -48,16 +48,18 @@ This sets up all future requests to use Basic HTTP authentication with the given
|
||||
### setHeader
|
||||
Set a header for all future requests. Takes a header and a value.
|
||||
|
||||
cordovaHttp.setHeader("Header", "Value", function() {
|
||||
cordovaHTTP.setHeader("Header", "Value", function() {
|
||||
console.log('success!');
|
||||
}, function() {
|
||||
console.log('error :(');
|
||||
});
|
||||
|
||||
### enableSSLPinning
|
||||
Enable or disable SSL pinning. To use SSL pinning you must include at least one .cer SSL certificate in your app project. For ios include your certificate in the root level of your bundle (just add the .cer file to your project/target at the root level). For android include your certificate in your project's platforms/android/assets folder. In both cases all .cer files found will be loaded automatically. If you only have a .pem certificate see this [stackoverflow answer](http://stackoverflow.com/a/16583429/3182729). You want to convert it to a DER encoded certificate with a .cer extension.
|
||||
Enable or disable SSL pinning. To use SSL pinning you must include at least one .cer SSL certificate in your app project. You can pin to your server certificate or to one of the issuing CA certificates. For ios include your certificate in the root level of your bundle (just add the .cer file to your project/target at the root level). For android include your certificate in your project's platforms/android/assets folder. In both cases all .cer files found will be loaded automatically. If you only have a .pem certificate see this [stackoverflow answer](http://stackoverflow.com/a/16583429/3182729). You want to convert it to a DER encoded certificate with a .cer extension.
|
||||
|
||||
cordovaHttp.enableSSLPinning(true, function() {
|
||||
As an alternative, you can store your .cer files in the www/certificates folder.
|
||||
|
||||
cordovaHTTP.enableSSLPinning(true, function() {
|
||||
console.log('success!');
|
||||
}, function() {
|
||||
console.log('error :(');
|
||||
@@ -66,7 +68,7 @@ Enable or disable SSL pinning. To use SSL pinning you must include at least one
|
||||
### acceptAllCerts
|
||||
Accept all SSL certificates. Or disable accepting all certificates.
|
||||
|
||||
cordovaHttp.acceptAllCerts(true, function() {
|
||||
cordovaHTTP.acceptAllCerts(true, function() {
|
||||
console.log('success!');
|
||||
}, function() {
|
||||
console.log('error :(');
|
||||
@@ -85,7 +87,7 @@ The success function receives a response object with 2 properties: status and da
|
||||
|
||||
Most apis will return JSON meaning you'll want to parse the data like in the example below:
|
||||
|
||||
cordovaHttp.post("https://google.com/, {
|
||||
cordovaHTTP.post("https://google.com/, {
|
||||
id: 12,
|
||||
message: "test"
|
||||
}, { Authorization: "OAuth2: token" }, function(response) {
|
||||
@@ -118,7 +120,7 @@ The error function receives a response object with 2 properties: status and erro
|
||||
### get
|
||||
Execute a GET request. Takes a URL, parameters, and headers. See the [post](#post) documentation for details on what is returned on success and failure.
|
||||
|
||||
cordovaHttp.get("https://google.com/, {
|
||||
cordovaHTTP.get("https://google.com/, {
|
||||
id: 12,
|
||||
message: "test"
|
||||
}, { Authorization: "OAuth2: token" }, function(response) {
|
||||
@@ -130,7 +132,7 @@ Execute a GET request. Takes a URL, parameters, and headers. See the [post](#p
|
||||
### uploadFile
|
||||
Uploads a file saved on the device. Takes a URL, parameters, headers, filePath, and the name of the parameter to pass the file along as. See the [post](#post) documentation for details on what is returned on success and failure.
|
||||
|
||||
cordovaHttp.uploadFile("https://google.com/, {
|
||||
cordovaHTTP.uploadFile("https://google.com/, {
|
||||
id: 12,
|
||||
message: "test"
|
||||
}, { Authorization: "OAuth2: token" }, "file:///somepicture.jpg", "picture", function(response) {
|
||||
@@ -142,7 +144,7 @@ Uploads a file saved on the device. Takes a URL, parameters, headers, filePath,
|
||||
### downloadFile
|
||||
Downloads a file and saves it to the device. Takes a URL, parameters, headers, and a filePath. See [post](#post) documentation for details on what is returned on failure. On success this function returns a cordova [FileEntry object](http://cordova.apache.org/docs/en/3.3.0/cordova_file_file.md.html#FileEntry).
|
||||
|
||||
cordovaHttp.downloadFile("https://google.com/, {
|
||||
cordovaHTTP.downloadFile("https://google.com/, {
|
||||
id: 12,
|
||||
message: "test"
|
||||
}, { Authorization: "OAuth2: token" }, "file:///somepicture.jpg", function(entry) {
|
||||
@@ -165,6 +167,17 @@ This plugin utilizes some awesome open source networking libraries. These are b
|
||||
|
||||
We made a few modifications to http-request. They can be found in a separate repo here: https://github.com/wymsee/http-request
|
||||
|
||||
## Limitations
|
||||
|
||||
This plugin isn't equivalent to using XMLHttpRequest or Ajax calls in Javascript.
|
||||
For instance, the following features are currently not supported:
|
||||
|
||||
- cookies support (a cookie set by a request isn't sent in subsequent requests)
|
||||
- read content of error responses (only the HTTP status code and message are returned)
|
||||
- read returned HTTP headers (e.g. in case security tokens are returned as headers)
|
||||
|
||||
Take this into account when using this plugin into your application.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
id="com.synconset.cordovaHTTP"
|
||||
version="0.1.1">
|
||||
version="0.1.4">
|
||||
|
||||
<name>SSL Pinning</name>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<engine name="cordova" version=">=3.0.0" />
|
||||
</engines>
|
||||
|
||||
<dependency id="org.apache.cordova.file" commit="r0.2.5" />
|
||||
<dependency id="org.apache.cordova.file" url="https://github.com/apache/cordova-plugin-file" commit="r0.2.5" />
|
||||
|
||||
<js-module src="www/cordovaHTTP.js" name="CordovaHttpPlugin">
|
||||
<clobbers target="plugins.CordovaHttpPlugin" />
|
||||
@@ -31,8 +31,8 @@
|
||||
<header-file src="src/ios/CordovaHttpPlugin.h" />
|
||||
<source-file src="src/ios/CordovaHttpPlugin.m" />
|
||||
|
||||
<header-file src="src/ios/HttpManager.h" />
|
||||
<source-file src="src/ios/HttpManager.m" />
|
||||
<header-file src="src/ios/HTTPManager.h" />
|
||||
<source-file src="src/ios/HTTPManager.m" />
|
||||
|
||||
<header-file src="src/ios/TextResponseSerializer.h" />
|
||||
<source-file src="src/ios/TextResponseSerializer.m" />
|
||||
|
||||
@@ -14,6 +14,8 @@ import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import org.apache.cordova.CallbackContext;
|
||||
import org.apache.cordova.file.FileUtils;
|
||||
|
||||
@@ -57,6 +59,8 @@ public class CordovaHttpDownload extends CordovaHttp implements Runnable {
|
||||
} catch (HttpRequestException e) {
|
||||
if (e.getCause() instanceof UnknownHostException) {
|
||||
this.respondWithError(0, "The host could not be resolved");
|
||||
} else if (e.getCause() instanceof SSLHandshakeException) {
|
||||
this.respondWithError("SSL handshake failed");
|
||||
} else {
|
||||
this.respondWithError("There was an error with the request");
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import org.apache.cordova.CallbackContext;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -51,6 +53,8 @@ public class CordovaHttpGet extends CordovaHttp implements Runnable {
|
||||
} catch (HttpRequestException e) {
|
||||
if (e.getCause() instanceof UnknownHostException) {
|
||||
this.respondWithError(0, "The host could not be resolved");
|
||||
} else if (e.getCause() instanceof SSLHandshakeException) {
|
||||
this.respondWithError("SSL handshake failed");
|
||||
} else {
|
||||
this.respondWithError("There was an error with the request");
|
||||
}
|
||||
|
||||
@@ -39,9 +39,9 @@ import com.github.kevinsawicki.http.HttpRequest;
|
||||
|
||||
public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
private static final String TAG = "CordovaHTTP";
|
||||
|
||||
|
||||
private HashMap<String, String> globalHeaders;
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
|
||||
super.initialize(cordova, webView);
|
||||
@@ -118,11 +118,11 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
loginInfo = "Basic " + Base64.encodeToString(loginInfo.getBytes(), Base64.NO_WRAP);
|
||||
this.globalHeaders.put("Authorization", loginInfo);
|
||||
}
|
||||
|
||||
|
||||
private void setHeader(String header, String value) {
|
||||
this.globalHeaders.put(header, value);
|
||||
}
|
||||
|
||||
|
||||
private void enableSSLPinning(boolean enable) throws GeneralSecurityException, IOException {
|
||||
if (enable) {
|
||||
AssetManager assetManager = cordova.getActivity().getAssets();
|
||||
@@ -137,7 +137,18 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// scan the www/certificates folder for .cer files as well
|
||||
files = assetManager.list("www/certificates");
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
index = files[i].lastIndexOf('.');
|
||||
if (index != -1) {
|
||||
if (files[i].substring(index).equals(".cer")) {
|
||||
cerFiles.add("www/certificates/" + files[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cerFiles.size(); i++) {
|
||||
InputStream in = cordova.getActivity().getAssets().open(cerFiles.get(i));
|
||||
InputStream caInput = new BufferedInputStream(in);
|
||||
@@ -148,22 +159,22 @@ public class CordovaHttpPlugin extends CordovaPlugin {
|
||||
CordovaHttp.enableSSLPinning(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private HashMap<String, String> addToMap(HashMap<String, String> map, JSONObject object) throws JSONException {
|
||||
HashMap<String, String> newMap = (HashMap<String, String>)map.clone();
|
||||
Iterator<?> i = object.keys();
|
||||
|
||||
|
||||
while (i.hasNext()) {
|
||||
String key = (String)i.next();
|
||||
newMap.put(key, object.getString(key));
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
||||
|
||||
private HashMap<String, Object> getMapFromJSONObject(JSONObject object) throws JSONException {
|
||||
HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
Iterator<?> i = object.keys();
|
||||
|
||||
|
||||
while(i.hasNext()) {
|
||||
String key = (String)i.next();
|
||||
map.put(key, object.get(key));
|
||||
|
||||
@@ -10,6 +10,8 @@ import org.apache.cordova.CallbackContext;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.github.kevinsawicki.http.HttpRequest;
|
||||
@@ -44,6 +46,8 @@ public class CordovaHttpPost extends CordovaHttp implements Runnable {
|
||||
} catch (HttpRequestException e) {
|
||||
if (e.getCause() instanceof UnknownHostException) {
|
||||
this.respondWithError(0, "The host could not be resolved");
|
||||
} else if (e.getCause() instanceof SSLHandshakeException) {
|
||||
this.respondWithError("SSL handshake failed");
|
||||
} else {
|
||||
this.respondWithError("There was an error with the request");
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.apache.cordova.CallbackContext;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
@@ -83,6 +85,8 @@ public class CordovaHttpUpload extends CordovaHttp implements Runnable {
|
||||
} catch (HttpRequestException e) {
|
||||
if (e.getCause() instanceof UnknownHostException) {
|
||||
this.respondWithError(0, "The host could not be resolved");
|
||||
} else if (e.getCause() instanceof SSLHandshakeException) {
|
||||
this.respondWithError("SSL handshake failed");
|
||||
} else {
|
||||
this.respondWithError("There was an error with the request");
|
||||
}
|
||||
|
||||
3
src/ios/AFNetworking/AFHTTPRequestOperation.h
Executable file → Normal file
3
src/ios/AFNetworking/AFHTTPRequestOperation.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFHTTPRequestOperation.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "AFURLConnectionOperation.h"
|
||||
#import "AFURLResponseSerialization.h"
|
||||
|
||||
/**
|
||||
`AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request.
|
||||
|
||||
18
src/ios/AFNetworking/AFHTTPRequestOperation.m
Executable file → Normal file
18
src/ios/AFNetworking/AFHTTPRequestOperation.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFHTTPRequestOperation.m
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -151,6 +151,8 @@ static dispatch_group_t http_request_operation_completion_group() {
|
||||
#pragma mark - AFURLRequestOperation
|
||||
|
||||
- (void)pause {
|
||||
[super pause];
|
||||
|
||||
u_int64_t offset = 0;
|
||||
if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) {
|
||||
offset = [(NSNumber *)[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedLongLongValue];
|
||||
@@ -164,11 +166,13 @@ static dispatch_group_t http_request_operation_completion_group() {
|
||||
}
|
||||
[mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"];
|
||||
self.request = mutableURLRequest;
|
||||
|
||||
[super pause];
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
@@ -176,7 +180,7 @@ static dispatch_group_t http_request_operation_completion_group() {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.responseSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -190,12 +194,12 @@ static dispatch_group_t http_request_operation_completion_group() {
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
AFHTTPRequestOperation *operation = [[[self class] allocWithZone:zone] initWithRequest:self.request];
|
||||
AFHTTPRequestOperation *operation = [super copyWithZone:zone];
|
||||
|
||||
operation.responseSerializer = [self.responseSerializer copyWithZone:zone];
|
||||
operation.completionQueue = self.completionQueue;
|
||||
operation.completionGroup = self.completionGroup;
|
||||
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
|
||||
38
src/ios/AFNetworking/AFHTTPRequestOperationManager.h
Executable file → Normal file
38
src/ios/AFNetworking/AFHTTPRequestOperationManager.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFHTTPRequestOperationManager.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -75,14 +75,14 @@
|
||||
|
||||
Network reachability status and change monitoring is available through the `reachabilityManager` property. Applications may choose to monitor network reachability conditions in order to prevent or suspend any outbound requests. See `AFNetworkReachabilityManager` for more details.
|
||||
|
||||
## NSCoding & NSCopying Caveats
|
||||
## NSSecureCoding & NSCopying Caveats
|
||||
|
||||
`AFHTTPRequestOperationManager` conforms to the `NSCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. There are a few minor caveats to keep in mind, however:
|
||||
`AFHTTPRequestOperationManager` conforms to the `NSSecureCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. There are a few minor caveats to keep in mind, however:
|
||||
|
||||
- Archives and copies of HTTP clients will be initialized with an empty operation queue.
|
||||
- NSCoding cannot serialize / deserialize block properties, so an archive of an HTTP client will not include any reachability callback block that may be set.
|
||||
- NSSecureCoding cannot serialize / deserialize block properties, so an archive of an HTTP client will not include any reachability callback block that may be set.
|
||||
*/
|
||||
@interface AFHTTPRequestOperationManager : NSObject <NSCoding, NSCopying>
|
||||
@interface AFHTTPRequestOperationManager : NSObject <NSSecureCoding, NSCopying>
|
||||
|
||||
/**
|
||||
The URL used to monitor reachability, and construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods.
|
||||
@@ -144,6 +144,20 @@
|
||||
*/
|
||||
@property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager;
|
||||
|
||||
///-------------------------------
|
||||
/// @name Managing Callback Queues
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
The dispatch queue for the `completionBlock` of request operations. If `NULL` (default), the main queue is used.
|
||||
*/
|
||||
@property (nonatomic, strong) dispatch_queue_t completionQueue;
|
||||
|
||||
/**
|
||||
The dispatch group for the `completionBlock` of request operations. If `NULL` (default), a private dispatch group is used.
|
||||
*/
|
||||
@property (nonatomic, strong) dispatch_group_t completionGroup;
|
||||
|
||||
///---------------------------------------------
|
||||
/// @name Creating and Initializing HTTP Clients
|
||||
///---------------------------------------------
|
||||
@@ -194,7 +208,7 @@
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (AFHTTPRequestOperation *)GET:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
|
||||
@@ -209,7 +223,7 @@
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (AFHTTPRequestOperation *)HEAD:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
|
||||
@@ -224,7 +238,7 @@
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (AFHTTPRequestOperation *)POST:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
|
||||
@@ -240,7 +254,7 @@
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (AFHTTPRequestOperation *)POST:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
@@ -256,7 +270,7 @@
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (AFHTTPRequestOperation *)PUT:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
|
||||
@@ -271,7 +285,7 @@
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (AFHTTPRequestOperation *)PATCH:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
|
||||
@@ -286,7 +300,7 @@
|
||||
@see -HTTPRequestOperationWithRequest:success:failure:
|
||||
*/
|
||||
- (AFHTTPRequestOperation *)DELETE:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
|
||||
|
||||
|
||||
47
src/ios/AFNetworking/AFHTTPRequestOperationManager.m
Executable file → Normal file
47
src/ios/AFNetworking/AFHTTPRequestOperationManager.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFHTTPRequestOperationManager.m
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -39,7 +39,7 @@
|
||||
@implementation AFHTTPRequestOperationManager
|
||||
|
||||
+ (instancetype)manager {
|
||||
return [[[self class] alloc] initWithBaseURL:nil];
|
||||
return [[self alloc] initWithBaseURL:nil];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
@@ -73,10 +73,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.operationQueue];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
@@ -107,6 +103,8 @@
|
||||
operation.securityPolicy = self.securityPolicy;
|
||||
|
||||
[operation setCompletionBlockWithSuccess:success failure:failure];
|
||||
operation.completionQueue = self.completionQueue;
|
||||
operation.completionGroup = self.completionGroup;
|
||||
|
||||
return operation;
|
||||
}
|
||||
@@ -114,19 +112,20 @@
|
||||
#pragma mark -
|
||||
|
||||
- (AFHTTPRequestOperation *)GET:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)HEAD:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
@@ -136,73 +135,89 @@
|
||||
success(requestOperation);
|
||||
}
|
||||
} failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)POST:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)POST:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:nil];
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)PUT:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PUT" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)PATCH:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PATCH" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (AFHTTPRequestOperation *)DELETE:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
|
||||
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"DELETE" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
|
||||
|
||||
[self.operationQueue addOperation:operation];
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.operationQueue];
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
NSURL *baseURL = [decoder decodeObjectForKey:NSStringFromSelector(@selector(baseURL))];
|
||||
@@ -212,8 +227,8 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.requestSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(requestSerializer))];
|
||||
self.responseSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))];
|
||||
self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
18
src/ios/AFNetworking/AFHTTPSessionManager.h
Executable file → Normal file
18
src/ios/AFNetworking/AFHTTPSessionManager.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFHTTPSessionManager.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090)
|
||||
|
||||
@interface AFHTTPSessionManager : AFURLSessionManager <NSCoding, NSCopying>
|
||||
@interface AFHTTPSessionManager : AFURLSessionManager <NSSecureCoding, NSCopying>
|
||||
|
||||
/**
|
||||
The URL used to monitor reachability, and construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods.
|
||||
@@ -137,7 +137,7 @@
|
||||
@see -dataTaskWithRequest:completionHandler:
|
||||
*/
|
||||
- (NSURLSessionDataTask *)GET:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
@see -dataTaskWithRequest:completionHandler:
|
||||
*/
|
||||
- (NSURLSessionDataTask *)HEAD:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
@see -dataTaskWithRequest:completionHandler:
|
||||
*/
|
||||
- (NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
@see -dataTaskWithRequest:completionHandler:
|
||||
*/
|
||||
- (NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
@@ -199,7 +199,7 @@
|
||||
@see -dataTaskWithRequest:completionHandler:
|
||||
*/
|
||||
- (NSURLSessionDataTask *)PUT:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
@see -dataTaskWithRequest:completionHandler:
|
||||
*/
|
||||
- (NSURLSessionDataTask *)PATCH:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
@see -dataTaskWithRequest:completionHandler:
|
||||
*/
|
||||
- (NSURLSessionDataTask *)DELETE:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
|
||||
|
||||
195
src/ios/AFNetworking/AFHTTPSessionManager.m
Executable file → Normal file
195
src/ios/AFNetworking/AFHTTPSessionManager.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFHTTPSessionManager.m
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090)
|
||||
|
||||
#import "AFHTTPRequestOperation.h"
|
||||
#import "AFURLRequestSerialization.h"
|
||||
#import "AFURLResponseSerialization.h"
|
||||
|
||||
#import <Availability.h>
|
||||
#import <Security/Security.h>
|
||||
@@ -84,10 +85,6 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#ifdef _SYSTEMCONFIGURATION_H
|
||||
@@ -108,84 +105,65 @@
|
||||
#pragma mark -
|
||||
|
||||
- (NSURLSessionDataTask *)GET:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
__block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
if (error) {
|
||||
if (failure) {
|
||||
failure(task, error);
|
||||
}
|
||||
} else {
|
||||
if (success) {
|
||||
success(task, responseObject);
|
||||
}
|
||||
}
|
||||
}];
|
||||
[dataTask resume];
|
||||
|
||||
[task resume];
|
||||
|
||||
return task;
|
||||
return dataTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)HEAD:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"HEAD" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
|
||||
__block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id __unused responseObject, NSError *error) {
|
||||
if (error) {
|
||||
if (failure) {
|
||||
failure(task, error);
|
||||
}
|
||||
} else {
|
||||
if (success) {
|
||||
success(task);
|
||||
}
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters success:^(NSURLSessionDataTask *task, __unused id responseObject) {
|
||||
if (success) {
|
||||
success(task);
|
||||
}
|
||||
}];
|
||||
} failure:failure];
|
||||
|
||||
[task resume];
|
||||
[dataTask resume];
|
||||
|
||||
return task;
|
||||
return dataTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
__block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
if (error) {
|
||||
if (failure) {
|
||||
failure(task, error);
|
||||
}
|
||||
} else {
|
||||
if (success) {
|
||||
success(task, responseObject);
|
||||
}
|
||||
}
|
||||
}];
|
||||
[dataTask resume];
|
||||
|
||||
[task resume];
|
||||
|
||||
return task;
|
||||
return dataTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)POST:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:nil];
|
||||
NSError *serializationError = nil;
|
||||
NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];
|
||||
if (serializationError) {
|
||||
if (failure) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||
failure(nil, serializationError);
|
||||
});
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
__block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:nil completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
if (error) {
|
||||
@@ -205,86 +183,101 @@
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)PUT:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PUT" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
__block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
if (error) {
|
||||
if (failure) {
|
||||
failure(task, error);
|
||||
}
|
||||
} else {
|
||||
if (success) {
|
||||
success(task, responseObject);
|
||||
}
|
||||
}
|
||||
}];
|
||||
[dataTask resume];
|
||||
|
||||
[task resume];
|
||||
|
||||
return task;
|
||||
return dataTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)PATCH:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PATCH" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
__block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
if (error) {
|
||||
if (failure) {
|
||||
failure(task, error);
|
||||
}
|
||||
} else {
|
||||
if (success) {
|
||||
success(task, responseObject);
|
||||
}
|
||||
}
|
||||
}];
|
||||
[dataTask resume];
|
||||
|
||||
[task resume];
|
||||
|
||||
return task;
|
||||
return dataTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)DELETE:(NSString *)URLString
|
||||
parameters:(NSDictionary *)parameters
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
|
||||
{
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"DELETE" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:nil];
|
||||
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters success:success failure:failure];
|
||||
|
||||
__block NSURLSessionDataTask *task = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
[dataTask resume];
|
||||
|
||||
return dataTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
|
||||
URLString:(NSString *)URLString
|
||||
parameters:(id)parameters
|
||||
success:(void (^)(NSURLSessionDataTask *, id))success
|
||||
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
|
||||
{
|
||||
NSError *serializationError = nil;
|
||||
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
|
||||
if (serializationError) {
|
||||
if (failure) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
|
||||
failure(nil, serializationError);
|
||||
});
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
__block NSURLSessionDataTask *dataTask = nil;
|
||||
dataTask = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
|
||||
if (error) {
|
||||
if (failure) {
|
||||
failure(task, error);
|
||||
failure(dataTask, error);
|
||||
}
|
||||
} else {
|
||||
if (success) {
|
||||
success(task, responseObject);
|
||||
success(dataTask, responseObject);
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
[task resume];
|
||||
|
||||
return task;
|
||||
return dataTask;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue];
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
NSURL *baseURL = [decoder decodeObjectForKey:NSStringFromSelector(@selector(baseURL))];
|
||||
NSURLSessionConfiguration *configuration = [decoder decodeObjectForKey:@"sessionConfiguration"];
|
||||
NSURL *baseURL = [decoder decodeObjectOfClass:[NSURL class] forKey:NSStringFromSelector(@selector(baseURL))];
|
||||
NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"];
|
||||
if (!configuration) {
|
||||
NSString *configurationIdentifier = [decoder decodeObjectForKey:@"identifier"];
|
||||
NSString *configurationIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:@"identifier"];
|
||||
if (configurationIdentifier) {
|
||||
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1100)
|
||||
configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:configurationIdentifier];
|
||||
#else
|
||||
configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:configurationIdentifier];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,8 +286,8 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.requestSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(requestSerializer))];
|
||||
self.responseSerializer = [decoder decodeObjectForKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))];
|
||||
self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
14
src/ios/AFNetworking/AFNetworkReachabilityManager.h
Executable file → Normal file
14
src/ios/AFNetworking/AFNetworkReachabilityManager.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFNetworkReachabilityManager.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,12 +23,6 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
#import <netinet/in.h>
|
||||
#import <netinet6/in6.h>
|
||||
#import <arpa/inet.h>
|
||||
#import <ifaddrs.h>
|
||||
#import <netdb.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
|
||||
AFNetworkReachabilityStatusUnknown = -1,
|
||||
AFNetworkReachabilityStatusNotReachable = 0,
|
||||
@@ -39,6 +33,8 @@ typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
|
||||
/**
|
||||
`AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces.
|
||||
|
||||
Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability.
|
||||
|
||||
See Apple's Reachability Sample Code (https://developer.apple.com/library/ios/samplecode/reachability/)
|
||||
|
||||
@warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined.
|
||||
@@ -86,11 +82,11 @@ typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
|
||||
/**
|
||||
Creates and returns a network reachability manager for the socket address.
|
||||
|
||||
@param address The socket address used to evaluate network reachability.
|
||||
@param address The socket address (`sockaddr_in`) used to evaluate network reachability.
|
||||
|
||||
@return An initialized network reachability manager, actively monitoring the specified socket address.
|
||||
*/
|
||||
+ (instancetype)managerForAddress:(const struct sockaddr_in *)address;
|
||||
+ (instancetype)managerForAddress:(const void *)address;
|
||||
|
||||
/**
|
||||
Initializes an instance of a network reachability manager from the specified reachability object.
|
||||
|
||||
17
src/ios/AFNetworking/AFNetworkReachabilityManager.m
Executable file → Normal file
17
src/ios/AFNetworking/AFNetworkReachabilityManager.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFNetworkReachabilityManager.m
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,6 +22,12 @@
|
||||
|
||||
#import "AFNetworkReachabilityManager.h"
|
||||
|
||||
#import <netinet/in.h>
|
||||
#import <netinet6/in6.h>
|
||||
#import <arpa/inet.h>
|
||||
#import <ifaddrs.h>
|
||||
#import <netdb.h>
|
||||
|
||||
NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change";
|
||||
NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem";
|
||||
|
||||
@@ -82,6 +88,7 @@ static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused targ
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
[notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }];
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
static const void * AFNetworkReachabilityRetainCallback(const void *info) {
|
||||
@@ -127,7 +134,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
return manager;
|
||||
}
|
||||
|
||||
+ (instancetype)managerForAddress:(const struct sockaddr_in *)address {
|
||||
+ (instancetype)managerForAddress:(const void *)address {
|
||||
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);
|
||||
|
||||
AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
|
||||
@@ -188,6 +195,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
if (strongSelf.networkReachabilityStatusBlock) {
|
||||
strongSelf.networkReachabilityStatusBlock(status);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
|
||||
@@ -206,6 +214,11 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
|
||||
AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(status);
|
||||
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
[notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }];
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
0
src/ios/AFNetworking/AFNetworking.h
Executable file → Normal file
0
src/ios/AFNetworking/AFNetworking.h
Executable file → Normal file
2
src/ios/AFNetworking/AFSecurityPolicy.h
Executable file → Normal file
2
src/ios/AFNetworking/AFSecurityPolicy.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFSecurity.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
152
src/ios/AFNetworking/AFSecurityPolicy.m
Executable file → Normal file
152
src/ios/AFNetworking/AFSecurityPolicy.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFSecurity.m
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,20 +22,40 @@
|
||||
|
||||
#import "AFSecurityPolicy.h"
|
||||
|
||||
// Equivalent of macro in <AssertMacros.h>, without causing compiler warning:
|
||||
// "'DebugAssert' is deprecated: first deprecated in OS X 10.8"
|
||||
#ifndef AF_Require
|
||||
#define AF_Require(assertion, exceptionLabel) \
|
||||
do { \
|
||||
if (__builtin_expect(!(assertion), 0)) { \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef AF_Require_noErr
|
||||
#define AF_Require_noErr(errorCode, exceptionLabel) \
|
||||
do { \
|
||||
if (__builtin_expect(0 != (errorCode), 0)) { \
|
||||
goto exceptionLabel; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if !defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
static NSData * AFSecKeyGetData(SecKeyRef key) {
|
||||
CFDataRef data = NULL;
|
||||
|
||||
#if defined(NS_BLOCK_ASSERTIONS)
|
||||
SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data);
|
||||
#else
|
||||
OSStatus status = SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data);
|
||||
NSCAssert(status == errSecSuccess, @"SecItemExport error: %ld", (long int)status);
|
||||
#endif
|
||||
|
||||
NSCParameterAssert(data);
|
||||
AF_Require_noErr(SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data), _out);
|
||||
|
||||
return (__bridge_transfer NSData *)data;
|
||||
|
||||
_out:
|
||||
if (data) {
|
||||
CFRelease(data);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -48,52 +68,55 @@ static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) {
|
||||
}
|
||||
|
||||
static id AFPublicKeyForCertificate(NSData *certificate) {
|
||||
SecCertificateRef allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate);
|
||||
NSCParameterAssert(allowedCertificate);
|
||||
id allowedPublicKey = nil;
|
||||
SecCertificateRef allowedCertificate;
|
||||
SecCertificateRef allowedCertificates[1];
|
||||
CFArrayRef tempCertificates = nil;
|
||||
SecPolicyRef policy = nil;
|
||||
SecTrustRef allowedTrust = nil;
|
||||
SecTrustResultType result;
|
||||
|
||||
SecCertificateRef allowedCertificates[] = {allowedCertificate};
|
||||
CFArrayRef tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL);
|
||||
allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate);
|
||||
AF_Require(allowedCertificate != NULL, _out);
|
||||
|
||||
SecPolicyRef policy = SecPolicyCreateBasicX509();
|
||||
SecTrustRef allowedTrust = NULL;
|
||||
#if defined(NS_BLOCK_ASSERTIONS)
|
||||
SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust);
|
||||
#else
|
||||
OSStatus status = SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust);
|
||||
NSCAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status);
|
||||
#endif
|
||||
allowedCertificates[0] = allowedCertificate;
|
||||
tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL);
|
||||
|
||||
SecTrustResultType result = 0;
|
||||
policy = SecPolicyCreateBasicX509();
|
||||
AF_Require_noErr(SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust), _out);
|
||||
AF_Require_noErr(SecTrustEvaluate(allowedTrust, &result), _out);
|
||||
|
||||
#if defined(NS_BLOCK_ASSERTIONS)
|
||||
SecTrustEvaluate(allowedTrust, &result);
|
||||
#else
|
||||
status = SecTrustEvaluate(allowedTrust, &result);
|
||||
NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status);
|
||||
#endif
|
||||
allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust);
|
||||
|
||||
SecKeyRef allowedPublicKey = SecTrustCopyPublicKey(allowedTrust);
|
||||
NSCParameterAssert(allowedPublicKey);
|
||||
_out:
|
||||
if (allowedTrust) {
|
||||
CFRelease(allowedTrust);
|
||||
}
|
||||
|
||||
CFRelease(allowedTrust);
|
||||
CFRelease(policy);
|
||||
CFRelease(tempCertificates);
|
||||
CFRelease(allowedCertificate);
|
||||
if (policy) {
|
||||
CFRelease(policy);
|
||||
}
|
||||
|
||||
return (__bridge_transfer id)allowedPublicKey;
|
||||
if (tempCertificates) {
|
||||
CFRelease(tempCertificates);
|
||||
}
|
||||
|
||||
if (allowedCertificate) {
|
||||
CFRelease(allowedCertificate);
|
||||
}
|
||||
|
||||
return allowedPublicKey;
|
||||
}
|
||||
|
||||
static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) {
|
||||
SecTrustResultType result = 0;
|
||||
BOOL isValid = NO;
|
||||
SecTrustResultType result;
|
||||
AF_Require_noErr(SecTrustEvaluate(serverTrust, &result), _out);
|
||||
|
||||
#if defined(NS_BLOCK_ASSERTIONS)
|
||||
SecTrustEvaluate(serverTrust, &result);
|
||||
#else
|
||||
OSStatus status = SecTrustEvaluate(serverTrust, &result);
|
||||
NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status);
|
||||
#endif
|
||||
isValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
|
||||
|
||||
return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
|
||||
_out:
|
||||
return isValid;
|
||||
}
|
||||
|
||||
static NSArray * AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
@@ -118,26 +141,24 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
SecCertificateRef someCertificates[] = {certificate};
|
||||
CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL);
|
||||
|
||||
SecTrustRef trust = NULL;
|
||||
|
||||
#if defined(NS_BLOCK_ASSERTIONS)
|
||||
SecTrustCreateWithCertificates(certificates, policy, &trust);
|
||||
|
||||
SecTrustRef trust;
|
||||
AF_Require_noErr(SecTrustCreateWithCertificates(certificates, policy, &trust), _out);
|
||||
|
||||
SecTrustResultType result;
|
||||
SecTrustEvaluate(trust, &result);
|
||||
#else
|
||||
OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &trust);
|
||||
NSCAssert(status == errSecSuccess, @"SecTrustCreateWithCertificates error: %ld", (long int)status);
|
||||
|
||||
SecTrustResultType result;
|
||||
status = SecTrustEvaluate(trust, &result);
|
||||
NSCAssert(status == errSecSuccess, @"SecTrustEvaluate error: %ld", (long int)status);
|
||||
#endif
|
||||
AF_Require_noErr(SecTrustEvaluate(trust, &result), _out);
|
||||
|
||||
[trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)];
|
||||
|
||||
CFRelease(trust);
|
||||
CFRelease(certificates);
|
||||
_out:
|
||||
if (trust) {
|
||||
CFRelease(trust);
|
||||
}
|
||||
|
||||
if (certificates) {
|
||||
CFRelease(certificates);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
CFRelease(policy);
|
||||
|
||||
@@ -158,12 +179,17 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
|
||||
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."];
|
||||
|
||||
NSMutableArray *certificates = [NSMutableArray arrayWithCapacity:[paths count]];
|
||||
for (NSString *path in paths) {
|
||||
NSData *certificateData = [NSData dataWithContentsOfFile:path];
|
||||
[certificates addObject:certificateData];
|
||||
}
|
||||
// also add certs from www/certificates
|
||||
paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"www/certificates"];
|
||||
for (NSString *path in paths) {
|
||||
NSData *certificateData = [NSData dataWithContentsOfFile:path];
|
||||
[certificates addObject:certificateData];
|
||||
}
|
||||
|
||||
_defaultPinnedCertificates = [[NSArray alloc] initWithArray:certificates];
|
||||
});
|
||||
@@ -206,7 +232,11 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
|
||||
if (self.pinnedCertificates) {
|
||||
NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]];
|
||||
for (NSData *certificate in self.pinnedCertificates) {
|
||||
[mutablePinnedPublicKeys addObject:AFPublicKeyForCertificate(certificate)];
|
||||
id publicKey = AFPublicKeyForCertificate(certificate);
|
||||
if (!publicKey) {
|
||||
continue;
|
||||
}
|
||||
[mutablePinnedPublicKeys addObject:publicKey];
|
||||
}
|
||||
self.pinnedPublicKeys = [NSArray arrayWithArray:mutablePinnedPublicKeys];
|
||||
} else {
|
||||
|
||||
55
src/ios/AFNetworking/AFURLConnectionOperation.h
Executable file → Normal file
55
src/ios/AFNetworking/AFURLConnectionOperation.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFURLConnectionOperation.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,6 +23,8 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <Availability.h>
|
||||
#import "AFURLRequestSerialization.h"
|
||||
#import "AFURLResponseSerialization.h"
|
||||
#import "AFSecurityPolicy.h"
|
||||
|
||||
/**
|
||||
@@ -63,6 +65,10 @@
|
||||
SSL with certificate pinning is strongly recommended for any application that transmits sensitive information to an external webservice.
|
||||
|
||||
Connections will be validated on all matching certificates with a `.cer` extension in the bundle root.
|
||||
|
||||
## App Extensions
|
||||
|
||||
When using AFNetworking in an App Extension, `#define AF_APP_EXTENSIONS` to avoid using unavailable APIs.
|
||||
|
||||
## NSCoding & NSCopying Conformance
|
||||
|
||||
@@ -80,7 +86,7 @@
|
||||
- Operation copies do not include `completionBlock`, as it often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ operation when copied.
|
||||
*/
|
||||
|
||||
@interface AFURLConnectionOperation : NSOperation <NSURLConnectionDelegate, NSURLConnectionDataDelegate, NSCoding, NSCopying>
|
||||
@interface AFURLConnectionOperation : NSOperation <NSURLConnectionDelegate, NSURLConnectionDataDelegate, NSSecureCoding, NSCopying>
|
||||
|
||||
///-------------------------------
|
||||
/// @name Accessing Run Loop Modes
|
||||
@@ -172,7 +178,7 @@
|
||||
/**
|
||||
The output stream that is used to write data received until the request is finished.
|
||||
|
||||
By default, data is accumulated into a buffer that is stored into `responseData` upon completion of the request. When `outputStream` is set, the data will not be accumulated into an internal buffer, and as a result, the `responseData` property of the completed request will be `nil`. The output stream will be scheduled in the network thread runloop upon being set.
|
||||
By default, data is accumulated into a buffer that is stored into `responseData` upon completion of the request, with the intermediary `outputStream` property set to `nil`. When `outputStream` is set, the data will not be accumulated into an internal buffer, and as a result, the `responseData` property of the completed request will be `nil`. The output stream will be scheduled in the network thread runloop upon being set.
|
||||
*/
|
||||
@property (nonatomic, strong) NSOutputStream *outputStream;
|
||||
|
||||
@@ -245,8 +251,8 @@
|
||||
Specifies that the operation should continue execution after the app has entered the background, and the expiration handler for that background task.
|
||||
|
||||
@param handler A handler to be called shortly before the application’s remaining background time reaches 0. The handler is wrapped in a block that cancels the operation, and cleans up and marks the end of execution, unlike the `handler` parameter in `UIApplication -beginBackgroundTaskWithExpirationHandler:`, which expects this to be done in the handler itself. The handler is called synchronously on the main thread, thus blocking the application’s suspension momentarily while the application is notified.
|
||||
*/
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
*/
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS)
|
||||
- (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(void (^)(void))handler;
|
||||
#endif
|
||||
|
||||
@@ -259,14 +265,14 @@
|
||||
|
||||
@param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread.
|
||||
*/
|
||||
- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))block;
|
||||
- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block;
|
||||
|
||||
/**
|
||||
Sets a callback to be called when an undetermined number of bytes have been downloaded from the server.
|
||||
|
||||
@param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread.
|
||||
*/
|
||||
- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead))block;
|
||||
- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block;
|
||||
|
||||
///-------------------------------------------------
|
||||
/// @name Setting NSURLConnection Delegate Callbacks
|
||||
@@ -307,41 +313,6 @@
|
||||
|
||||
@end
|
||||
|
||||
///----------------
|
||||
/// @name Constants
|
||||
///----------------
|
||||
|
||||
/**
|
||||
## User info dictionary keys
|
||||
|
||||
These keys may exist in the user info dictionary, in addition to those defined for NSError.
|
||||
|
||||
- `NSString * const AFNetworkingOperationFailingURLRequestErrorKey`
|
||||
- `NSString * const AFNetworkingOperationFailingURLResponseErrorKey`
|
||||
|
||||
### 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 `AFNetworkingErrorDomain`.
|
||||
|
||||
`AFNetworkingOperationFailingURLResponseErrorKey`
|
||||
The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFNetworkingErrorDomain`.
|
||||
|
||||
## Error Domains
|
||||
|
||||
The following error domain is predefined.
|
||||
|
||||
- `NSString * const AFNetworkingErrorDomain`
|
||||
|
||||
### Constants
|
||||
|
||||
`AFNetworkingErrorDomain`
|
||||
AFNetworking errors. Error codes for `AFNetworkingErrorDomain` correspond to codes in `NSURLErrorDomain`.
|
||||
*/
|
||||
extern NSString * const AFNetworkingErrorDomain;
|
||||
extern NSString * const AFNetworkingOperationFailingURLRequestErrorKey;
|
||||
extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey;
|
||||
|
||||
///--------------------
|
||||
/// @name Notifications
|
||||
///--------------------
|
||||
|
||||
442
src/ios/AFNetworking/AFURLConnectionOperation.m
Executable file → Normal file
442
src/ios/AFNetworking/AFURLConnectionOperation.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFURLConnectionOperation.m
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -38,7 +38,7 @@ typedef NS_ENUM(NSInteger, AFOperationState) {
|
||||
AFOperationFinishedState = 3,
|
||||
};
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS)
|
||||
typedef UIBackgroundTaskIdentifier AFBackgroundTaskIdentifier;
|
||||
#else
|
||||
typedef id AFBackgroundTaskIdentifier;
|
||||
@@ -66,14 +66,10 @@ static dispatch_queue_t url_request_operation_completion_queue() {
|
||||
|
||||
static NSString * const kAFNetworkingLockName = @"com.alamofire.networking.operation.lock";
|
||||
|
||||
NSString * const AFNetworkingErrorDomain = @"AFNetworkingErrorDomain";
|
||||
NSString * const AFNetworkingOperationFailingURLRequestErrorKey = @"AFNetworkingOperationFailingURLRequestErrorKey";
|
||||
NSString * const AFNetworkingOperationFailingURLResponseErrorKey = @"AFNetworkingOperationFailingURLResponseErrorKey";
|
||||
|
||||
NSString * const AFNetworkingOperationDidStartNotification = @"com.alamofire.networking.operation.start";
|
||||
NSString * const AFNetworkingOperationDidFinishNotification = @"com.alamofire.networking.operation.finish";
|
||||
|
||||
typedef void (^AFURLConnectionOperationProgressBlock)(NSUInteger bytes, NSInteger totalBytes, NSInteger totalBytesExpected);
|
||||
typedef void (^AFURLConnectionOperationProgressBlock)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected);
|
||||
typedef void (^AFURLConnectionOperationAuthenticationChallengeBlock)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge);
|
||||
typedef NSCachedURLResponse * (^AFURLConnectionOperationCacheResponseBlock)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse);
|
||||
typedef NSURLRequest * (^AFURLConnectionOperationRedirectResponseBlock)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse);
|
||||
@@ -121,8 +117,20 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
return NO;
|
||||
case AFOperationPausedState:
|
||||
return toState == AFOperationReadyState;
|
||||
default:
|
||||
return YES;
|
||||
default: {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
switch (toState) {
|
||||
case AFOperationPausedState:
|
||||
case AFOperationReadyState:
|
||||
case AFOperationExecutingState:
|
||||
case AFOperationFinishedState:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +144,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
@property (readwrite, nonatomic, strong) NSData *responseData;
|
||||
@property (readwrite, nonatomic, copy) NSString *responseString;
|
||||
@property (readwrite, nonatomic, assign) NSStringEncoding responseStringEncoding;
|
||||
@property (readwrite, nonatomic, assign) NSInteger totalBytesRead;
|
||||
@property (readwrite, nonatomic, assign) long long totalBytesRead;
|
||||
@property (readwrite, nonatomic, assign) AFBackgroundTaskIdentifier backgroundTaskIdentifier;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock uploadProgress;
|
||||
@property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock downloadProgress;
|
||||
@@ -180,7 +188,9 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
_state = AFOperationReadyState;
|
||||
|
||||
self.lock = [[NSRecursiveLock alloc] init];
|
||||
self.lock.name = kAFNetworkingLockName;
|
||||
|
||||
@@ -190,8 +200,6 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
|
||||
self.shouldUseCredentialStorage = YES;
|
||||
|
||||
self.state = AFOperationReadyState;
|
||||
|
||||
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
|
||||
|
||||
return self;
|
||||
@@ -203,7 +211,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
_outputStream = nil;
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS)
|
||||
if (_backgroundTaskIdentifier) {
|
||||
[[UIApplication sharedApplication] endBackgroundTask:_backgroundTaskIdentifier];
|
||||
_backgroundTaskIdentifier = UIBackgroundTaskInvalid;
|
||||
@@ -211,10 +219,185 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, state: %@, cancelled: %@ request: %@, response: %@>", NSStringFromClass([self class]), self, AFKeyPathFromOperationState(self.state), ([self isCancelled] ? @"YES" : @"NO"), self.request, self.response];
|
||||
#pragma mark -
|
||||
|
||||
- (void)setResponseData:(NSData *)responseData {
|
||||
[self.lock lock];
|
||||
if (!responseData) {
|
||||
_responseData = nil;
|
||||
} else {
|
||||
_responseData = [NSData dataWithBytes:responseData.bytes length:responseData.length];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (NSString *)responseString {
|
||||
[self.lock lock];
|
||||
if (!_responseString && self.response && self.responseData) {
|
||||
self.responseString = [[NSString alloc] initWithData:self.responseData encoding:self.responseStringEncoding];
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
return _responseString;
|
||||
}
|
||||
|
||||
- (NSStringEncoding)responseStringEncoding {
|
||||
[self.lock lock];
|
||||
if (!_responseStringEncoding && self.response) {
|
||||
NSStringEncoding stringEncoding = NSUTF8StringEncoding;
|
||||
if (self.response.textEncodingName) {
|
||||
CFStringEncoding IANAEncoding = CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)self.response.textEncodingName);
|
||||
if (IANAEncoding != kCFStringEncodingInvalidId) {
|
||||
stringEncoding = CFStringConvertEncodingToNSStringEncoding(IANAEncoding);
|
||||
}
|
||||
}
|
||||
|
||||
self.responseStringEncoding = stringEncoding;
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
return _responseStringEncoding;
|
||||
}
|
||||
|
||||
- (NSInputStream *)inputStream {
|
||||
return self.request.HTTPBodyStream;
|
||||
}
|
||||
|
||||
- (void)setInputStream:(NSInputStream *)inputStream {
|
||||
NSMutableURLRequest *mutableRequest = [self.request mutableCopy];
|
||||
mutableRequest.HTTPBodyStream = inputStream;
|
||||
self.request = mutableRequest;
|
||||
}
|
||||
|
||||
- (NSOutputStream *)outputStream {
|
||||
if (!_outputStream) {
|
||||
self.outputStream = [NSOutputStream outputStreamToMemory];
|
||||
}
|
||||
|
||||
return _outputStream;
|
||||
}
|
||||
|
||||
- (void)setOutputStream:(NSOutputStream *)outputStream {
|
||||
[self.lock lock];
|
||||
if (outputStream != _outputStream) {
|
||||
if (_outputStream) {
|
||||
[_outputStream close];
|
||||
}
|
||||
|
||||
_outputStream = outputStream;
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS)
|
||||
- (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(void (^)(void))handler {
|
||||
[self.lock lock];
|
||||
if (!self.backgroundTaskIdentifier) {
|
||||
UIApplication *application = [UIApplication sharedApplication];
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
|
||||
if (strongSelf) {
|
||||
[strongSelf cancel];
|
||||
|
||||
[application endBackgroundTask:strongSelf.backgroundTaskIdentifier];
|
||||
strongSelf.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
|
||||
}
|
||||
}];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setState:(AFOperationState)state {
|
||||
if (!AFStateTransitionIsValid(self.state, state, [self isCancelled])) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
NSString *oldStateKey = AFKeyPathFromOperationState(self.state);
|
||||
NSString *newStateKey = AFKeyPathFromOperationState(state);
|
||||
|
||||
[self willChangeValueForKey:newStateKey];
|
||||
[self willChangeValueForKey:oldStateKey];
|
||||
_state = state;
|
||||
[self didChangeValueForKey:oldStateKey];
|
||||
[self didChangeValueForKey:newStateKey];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)pause {
|
||||
if ([self isPaused] || [self isFinished] || [self isCancelled]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
if ([self isExecuting]) {
|
||||
[self performSelector:@selector(operationDidPause) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
[notificationCenter postNotificationName:AFNetworkingOperationDidFinishNotification object:self];
|
||||
});
|
||||
}
|
||||
|
||||
self.state = AFOperationPausedState;
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)operationDidPause {
|
||||
[self.lock lock];
|
||||
[self.connection cancel];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (BOOL)isPaused {
|
||||
return self.state == AFOperationPausedState;
|
||||
}
|
||||
|
||||
- (void)resume {
|
||||
if (![self isPaused]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
self.state = AFOperationReadyState;
|
||||
|
||||
[self start];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block {
|
||||
self.uploadProgress = block;
|
||||
}
|
||||
|
||||
- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block {
|
||||
self.downloadProgress = block;
|
||||
}
|
||||
|
||||
- (void)setWillSendRequestForAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block {
|
||||
self.authenticationChallenge = block;
|
||||
}
|
||||
|
||||
- (void)setCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block {
|
||||
self.cacheResponse = block;
|
||||
}
|
||||
|
||||
- (void)setRedirectResponseBlock:(NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block {
|
||||
self.redirectResponse = block;
|
||||
}
|
||||
|
||||
#pragma mark - NSOperation
|
||||
|
||||
- (void)setCompletionBlock:(void (^)(void))block {
|
||||
[self.lock lock];
|
||||
if (!block) {
|
||||
@@ -242,170 +425,6 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (NSInputStream *)inputStream {
|
||||
return self.request.HTTPBodyStream;
|
||||
}
|
||||
|
||||
- (void)setInputStream:(NSInputStream *)inputStream {
|
||||
NSMutableURLRequest *mutableRequest = [self.request mutableCopy];
|
||||
mutableRequest.HTTPBodyStream = inputStream;
|
||||
self.request = mutableRequest;
|
||||
}
|
||||
|
||||
- (NSOutputStream *)outputStream {
|
||||
if (!_outputStream) {
|
||||
self.outputStream = [NSOutputStream outputStreamToMemory];
|
||||
}
|
||||
|
||||
return _outputStream;
|
||||
}
|
||||
|
||||
- (void)setOutputStream:(NSOutputStream *)outputStream {
|
||||
[self.lock lock];
|
||||
if (outputStream != _outputStream) {
|
||||
if (_outputStream) {
|
||||
[_outputStream close];
|
||||
}
|
||||
_outputStream = outputStream;
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
- (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(void (^)(void))handler {
|
||||
[self.lock lock];
|
||||
if (!self.backgroundTaskIdentifier) {
|
||||
UIApplication *application = [UIApplication sharedApplication];
|
||||
__weak __typeof(self)weakSelf = self;
|
||||
self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
|
||||
if (handler) {
|
||||
handler();
|
||||
}
|
||||
|
||||
if (strongSelf) {
|
||||
[strongSelf cancel];
|
||||
|
||||
[application endBackgroundTask:strongSelf.backgroundTaskIdentifier];
|
||||
strongSelf.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
|
||||
}
|
||||
}];
|
||||
}
|
||||
[self.lock unlock];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))block {
|
||||
self.uploadProgress = block;
|
||||
}
|
||||
|
||||
- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead))block {
|
||||
self.downloadProgress = block;
|
||||
}
|
||||
|
||||
- (void)setWillSendRequestForAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block {
|
||||
self.authenticationChallenge = block;
|
||||
}
|
||||
|
||||
- (void)setCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block {
|
||||
self.cacheResponse = block;
|
||||
}
|
||||
|
||||
- (void)setRedirectResponseBlock:(NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block {
|
||||
self.redirectResponse = block;
|
||||
}
|
||||
|
||||
- (void)setState:(AFOperationState)state {
|
||||
if (!AFStateTransitionIsValid(self.state, state, [self isCancelled])) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
NSString *oldStateKey = AFKeyPathFromOperationState(self.state);
|
||||
NSString *newStateKey = AFKeyPathFromOperationState(state);
|
||||
|
||||
[self willChangeValueForKey:newStateKey];
|
||||
[self willChangeValueForKey:oldStateKey];
|
||||
_state = state;
|
||||
[self didChangeValueForKey:oldStateKey];
|
||||
[self didChangeValueForKey:newStateKey];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (NSString *)responseString {
|
||||
[self.lock lock];
|
||||
if (!_responseString && self.response && self.responseData) {
|
||||
self.responseString = [[NSString alloc] initWithData:self.responseData encoding:self.responseStringEncoding];
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
return _responseString;
|
||||
}
|
||||
|
||||
- (NSStringEncoding)responseStringEncoding {
|
||||
[self.lock lock];
|
||||
if (!_responseStringEncoding && self.response) {
|
||||
NSStringEncoding stringEncoding = NSUTF8StringEncoding;
|
||||
if (self.response.textEncodingName) {
|
||||
CFStringEncoding IANAEncoding = CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)self.response.textEncodingName);
|
||||
if (IANAEncoding != kCFStringEncodingInvalidId) {
|
||||
stringEncoding = CFStringConvertEncodingToNSStringEncoding(IANAEncoding);
|
||||
}
|
||||
}
|
||||
|
||||
self.responseStringEncoding = stringEncoding;
|
||||
}
|
||||
[self.lock unlock];
|
||||
|
||||
return _responseStringEncoding;
|
||||
}
|
||||
|
||||
- (void)pause {
|
||||
if ([self isPaused] || [self isFinished] || [self isCancelled]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
|
||||
if ([self isExecuting]) {
|
||||
[self performSelector:@selector(operationDidPause) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
[notificationCenter postNotificationName:AFNetworkingOperationDidFinishNotification object:self];
|
||||
});
|
||||
}
|
||||
|
||||
self.state = AFOperationPausedState;
|
||||
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)operationDidPause {
|
||||
[self.lock lock];
|
||||
[self.connection cancel];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (BOOL)isPaused {
|
||||
return self.state == AFOperationPausedState;
|
||||
}
|
||||
|
||||
- (void)resume {
|
||||
if (![self isPaused]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self.lock lock];
|
||||
self.state = AFOperationReadyState;
|
||||
|
||||
[self start];
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
#pragma mark - NSOperation
|
||||
|
||||
- (BOOL)isReady {
|
||||
return self.state == AFOperationReadyState && [super isReady];
|
||||
}
|
||||
@@ -445,6 +464,7 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
[self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode];
|
||||
}
|
||||
|
||||
[self.outputStream open];
|
||||
[self.connection start];
|
||||
}
|
||||
[self.lock unlock];
|
||||
@@ -554,6 +574,12 @@ static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperat
|
||||
return [operations arrayByAddingObject:batchedOperation];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, state: %@, cancelled: %@ request: %@, response: %@>", NSStringFromClass([self class]), self, AFKeyPathFromOperationState(self.state), ([self isCancelled] ? @"YES" : @"NO"), self.request, self.response];
|
||||
}
|
||||
|
||||
#pragma mark - NSURLConnectionDelegate
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection
|
||||
@@ -604,19 +630,17 @@ willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challe
|
||||
totalBytesWritten:(NSInteger)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
|
||||
{
|
||||
if (self.uploadProgress) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.uploadProgress) {
|
||||
self.uploadProgress((NSUInteger)bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection __unused *)connection
|
||||
didReceiveResponse:(NSURLResponse *)response
|
||||
{
|
||||
self.response = response;
|
||||
|
||||
[self.outputStream open];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection __unused *)connection
|
||||
@@ -649,34 +673,40 @@ didReceiveResponse:(NSURLResponse *)response
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.totalBytesRead += (NSInteger)length;
|
||||
self.totalBytesRead += (long long)length;
|
||||
|
||||
if (self.downloadProgress) {
|
||||
self.downloadProgress(length, self.totalBytesRead, (NSInteger)self.response.expectedContentLength);
|
||||
self.downloadProgress(length, self.totalBytesRead, self.response.expectedContentLength);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection __unused *)connection {
|
||||
self.responseData = [self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
|
||||
|
||||
|
||||
[self.outputStream close];
|
||||
|
||||
[self finish];
|
||||
|
||||
if (self.responseData) {
|
||||
self.outputStream = nil;
|
||||
}
|
||||
|
||||
self.connection = nil;
|
||||
|
||||
[self finish];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection __unused *)connection
|
||||
didFailWithError:(NSError *)error
|
||||
{
|
||||
self.error = error;
|
||||
|
||||
|
||||
[self.outputStream close];
|
||||
|
||||
[self finish];
|
||||
|
||||
if (self.responseData) {
|
||||
self.outputStream = nil;
|
||||
}
|
||||
|
||||
self.connection = nil;
|
||||
|
||||
[self finish];
|
||||
}
|
||||
|
||||
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
|
||||
@@ -693,21 +723,25 @@ didReceiveResponse:(NSURLResponse *)response
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
NSURLRequest *request = [decoder decodeObjectForKey:NSStringFromSelector(@selector(request))];
|
||||
NSURLRequest *request = [decoder decodeObjectOfClass:[NSURLRequest class] forKey:NSStringFromSelector(@selector(request))];
|
||||
|
||||
self = [self initWithRequest:request];
|
||||
if (!self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.state = (AFOperationState)[decoder decodeIntegerForKey:NSStringFromSelector(@selector(state))];
|
||||
self.response = [decoder decodeObjectForKey:NSStringFromSelector(@selector(response))];
|
||||
self.error = [decoder decodeObjectForKey:NSStringFromSelector(@selector(error))];
|
||||
self.responseData = [decoder decodeObjectForKey:NSStringFromSelector(@selector(responseData))];
|
||||
self.totalBytesRead = [decoder decodeIntegerForKey:NSStringFromSelector(@selector(totalBytesRead))];
|
||||
|
||||
self.state = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(state))] integerValue];
|
||||
self.response = [decoder decodeObjectOfClass:[NSHTTPURLResponse class] forKey:NSStringFromSelector(@selector(response))];
|
||||
self.error = [decoder decodeObjectOfClass:[NSError class] forKey:NSStringFromSelector(@selector(error))];
|
||||
self.responseData = [decoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(responseData))];
|
||||
self.totalBytesRead = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(totalBytesRead))] longLongValue];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
90
src/ios/AFNetworking/AFURLRequestSerialization.h
Executable file → Normal file
90
src/ios/AFNetworking/AFURLRequestSerialization.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFSerialization.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
For example, a JSON request serializer may set the HTTP body of the request to a JSON representation, and set the `Content-Type` HTTP header field value to `application/json`.
|
||||
*/
|
||||
@protocol AFURLRequestSerialization <NSObject, NSCoding, NSCopying>
|
||||
@protocol AFURLRequestSerialization <NSObject, NSSecureCoding, NSCopying>
|
||||
|
||||
/**
|
||||
Returns a request with the specified parameters encoded into a copy of the original request.
|
||||
@@ -135,6 +135,15 @@ typedef NS_ENUM(NSUInteger, AFHTTPRequestQueryStringSerializationStyle) {
|
||||
- (void)setValue:(NSString *)value
|
||||
forHTTPHeaderField:(NSString *)field;
|
||||
|
||||
/**
|
||||
Returns the value for the HTTP headers set in the request serializer.
|
||||
|
||||
@param field The HTTP header to retrieve the default value for
|
||||
|
||||
@return The value set as default for the specified header, or `nil`
|
||||
*/
|
||||
- (NSString *)valueForHTTPHeaderField:(NSString *)field;
|
||||
|
||||
/**
|
||||
Sets the "Authorization" HTTP header set in request objects made by the HTTP client to a basic authentication value with Base64-encoded username and password. This overwrites any existing value for this header.
|
||||
|
||||
@@ -145,11 +154,9 @@ forHTTPHeaderField:(NSString *)field;
|
||||
password:(NSString *)password;
|
||||
|
||||
/**
|
||||
Sets the "Authorization" HTTP header set in request objects made by the HTTP client to a token-based authentication value, such as an OAuth access token. This overwrites any existing value for this header.
|
||||
|
||||
@param token The authentication token
|
||||
@deprecated This method has been deprecated. Use -setValue:forHTTPHeaderField: instead.
|
||||
*/
|
||||
- (void)setAuthorizationHeaderFieldWithToken:(NSString *)token;
|
||||
- (void)setAuthorizationHeaderFieldWithToken:(NSString *)token DEPRECATED_ATTRIBUTE;
|
||||
|
||||
|
||||
/**
|
||||
@@ -256,9 +263,6 @@ forHTTPHeaderField:(NSString *)field;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
extern NSUInteger const kAFUploadStream3GSuggestedPacketSize;
|
||||
extern NSTimeInterval const kAFUploadStream3GSuggestedDelay;
|
||||
|
||||
/**
|
||||
The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `AFHTTPRequestSerializer -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:`.
|
||||
*/
|
||||
@@ -308,7 +312,7 @@ extern NSTimeInterval const kAFUploadStream3GSuggestedDelay;
|
||||
- (void)appendPartWithInputStream:(NSInputStream *)inputStream
|
||||
name:(NSString *)name
|
||||
fileName:(NSString *)fileName
|
||||
length:(NSUInteger)length
|
||||
length:(int64_t)length
|
||||
mimeType:(NSString *)mimeType;
|
||||
|
||||
/**
|
||||
@@ -339,7 +343,7 @@ extern NSTimeInterval const kAFUploadStream3GSuggestedDelay;
|
||||
Appends HTTP headers, followed by the encoded data and the multipart form boundary.
|
||||
|
||||
@param headers The HTTP headers to be appended to the form data.
|
||||
@param body The data to be encoded and appended to the form data.
|
||||
@param body The data to be encoded and appended to the form data. This parameter must not be `nil`.
|
||||
*/
|
||||
- (void)appendPartWithHeaders:(NSDictionary *)headers
|
||||
body:(NSData *)body;
|
||||
@@ -357,22 +361,6 @@ extern NSTimeInterval const kAFUploadStream3GSuggestedDelay;
|
||||
|
||||
@end
|
||||
|
||||
///----------------
|
||||
/// @name Constants
|
||||
///----------------
|
||||
|
||||
/**
|
||||
## Throttling Bandwidth for HTTP Request Input Streams
|
||||
|
||||
@see -throttleBandwidthWithPacketSize:delay:
|
||||
|
||||
`kAFUploadStream3GSuggestedPacketSize`
|
||||
Maximum packet size, in number of bytes. Equal to 16kb.
|
||||
|
||||
`kAFUploadStream3GSuggestedDelay`
|
||||
Duration of delay each time a packet is read. Equal to 0.2 seconds.
|
||||
*/
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface AFJSONRequestSerializer : AFHTTPRequestSerializer
|
||||
@@ -415,3 +403,51 @@ extern NSTimeInterval const kAFUploadStream3GSuggestedDelay;
|
||||
writeOptions:(NSPropertyListWriteOptions)writeOptions;
|
||||
|
||||
@end
|
||||
|
||||
///----------------
|
||||
/// @name Constants
|
||||
///----------------
|
||||
|
||||
/**
|
||||
## Error Domains
|
||||
|
||||
The following error domain is predefined.
|
||||
|
||||
- `NSString * const AFURLRequestSerializationErrorDomain`
|
||||
|
||||
### Constants
|
||||
|
||||
`AFURLRequestSerializationErrorDomain`
|
||||
AFURLRequestSerializer errors. Error codes for `AFURLRequestSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`.
|
||||
*/
|
||||
extern NSString * const AFURLRequestSerializationErrorDomain;
|
||||
|
||||
/**
|
||||
## User info dictionary keys
|
||||
|
||||
These keys may exist in the user info dictionary, in addition to those defined for NSError.
|
||||
|
||||
- `NSString * const AFNetworkingOperationFailingURLResponseErrorKey`
|
||||
|
||||
### 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`.
|
||||
*/
|
||||
extern NSString * const AFNetworkingOperationFailingURLRequestErrorKey;
|
||||
|
||||
/**
|
||||
## Throttling Bandwidth for HTTP Request Input Streams
|
||||
|
||||
@see -throttleBandwidthWithPacketSize:delay:
|
||||
|
||||
### Constants
|
||||
|
||||
`kAFUploadStream3GSuggestedPacketSize`
|
||||
Maximum packet size, in number of bytes. Equal to 16kb.
|
||||
|
||||
`kAFUploadStream3GSuggestedDelay`
|
||||
Duration of delay each time a packet is read. Equal to 0.2 seconds.
|
||||
*/
|
||||
extern NSUInteger const kAFUploadStream3GSuggestedPacketSize;
|
||||
extern NSTimeInterval const kAFUploadStream3GSuggestedDelay;
|
||||
|
||||
240
src/ios/AFNetworking/AFURLRequestSerialization.m
Executable file → Normal file
240
src/ios/AFNetworking/AFURLRequestSerialization.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFSerialization.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,7 +22,14 @@
|
||||
|
||||
#import "AFURLRequestSerialization.h"
|
||||
|
||||
extern NSString * const AFNetworkingErrorDomain;
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
#else
|
||||
#import <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
NSString * const AFURLRequestSerializationErrorDomain = @"com.alamofire.error.serialization.request";
|
||||
NSString * const AFNetworkingOperationFailingURLRequestErrorKey = @"com.alamofire.serialization.request.error.response";
|
||||
|
||||
typedef NSString * (^AFQueryStringSerializationBlock)(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error);
|
||||
|
||||
@@ -162,7 +169,20 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
|
||||
|
||||
#pragma mark -
|
||||
|
||||
static NSArray * AFHTTPRequestSerializerObservedKeyPaths() {
|
||||
static NSArray *_AFHTTPRequestSerializerObservedKeyPaths = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_AFHTTPRequestSerializerObservedKeyPaths = @[NSStringFromSelector(@selector(allowsCellularAccess)), NSStringFromSelector(@selector(cachePolicy)), NSStringFromSelector(@selector(HTTPShouldHandleCookies)), NSStringFromSelector(@selector(HTTPShouldUsePipelining)), NSStringFromSelector(@selector(networkServiceType)), NSStringFromSelector(@selector(timeoutInterval))];
|
||||
});
|
||||
|
||||
return _AFHTTPRequestSerializerObservedKeyPaths;
|
||||
}
|
||||
|
||||
static void *AFHTTPRequestSerializerObserverContext = &AFHTTPRequestSerializerObserverContext;
|
||||
|
||||
@interface AFHTTPRequestSerializer ()
|
||||
@property (readwrite, nonatomic, strong) NSMutableSet *mutableObservedChangedKeyPaths;
|
||||
@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableHTTPRequestHeaders;
|
||||
@property (readwrite, nonatomic, assign) AFHTTPRequestQueryStringSerializationStyle queryStringSerializationStyle;
|
||||
@property (readwrite, nonatomic, copy) AFQueryStringSerializationBlock queryStringSerialization;
|
||||
@@ -181,12 +201,6 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
|
||||
}
|
||||
|
||||
self.stringEncoding = NSUTF8StringEncoding;
|
||||
self.allowsCellularAccess = YES;
|
||||
self.cachePolicy = NSURLRequestUseProtocolCachePolicy;
|
||||
self.HTTPShouldHandleCookies = YES;
|
||||
self.HTTPShouldUsePipelining = NO;
|
||||
self.networkServiceType = NSURLNetworkServiceTypeDefault;
|
||||
self.timeoutInterval = 60;
|
||||
|
||||
self.mutableHTTPRequestHeaders = [NSMutableDictionary dictionary];
|
||||
|
||||
@@ -204,7 +218,7 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
// User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43
|
||||
userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] ? [[UIScreen mainScreen] scale] : 1.0f)];
|
||||
userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], (__bridge id)CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleVersionKey) ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
|
||||
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]];
|
||||
#endif
|
||||
@@ -222,20 +236,39 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
|
||||
// HTTP Method Definitions; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
|
||||
self.HTTPMethodsEncodingParametersInURI = [NSSet setWithObjects:@"GET", @"HEAD", @"DELETE", nil];
|
||||
|
||||
self.mutableObservedChangedKeyPaths = [NSMutableSet set];
|
||||
for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
|
||||
[self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
|
||||
[self removeObserver:self forKeyPath:keyPath context:AFHTTPRequestSerializerObserverContext];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSDictionary *)HTTPRequestHeaders {
|
||||
return [NSDictionary dictionaryWithDictionary:self.mutableHTTPRequestHeaders];
|
||||
}
|
||||
|
||||
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field {
|
||||
- (void)setValue:(NSString *)value
|
||||
forHTTPHeaderField:(NSString *)field
|
||||
{
|
||||
[self.mutableHTTPRequestHeaders setValue:value forKey:field];
|
||||
}
|
||||
|
||||
- (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username password:(NSString *)password {
|
||||
- (NSString *)valueForHTTPHeaderField:(NSString *)field {
|
||||
return [self.mutableHTTPRequestHeaders valueForKey:field];
|
||||
}
|
||||
|
||||
- (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username
|
||||
password:(NSString *)password
|
||||
{
|
||||
NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", username, password];
|
||||
[self setValue:[NSString stringWithFormat:@"Basic %@", AFBase64EncodedStringFromString(basicAuthCredentials)] forHTTPHeaderField:@"Authorization"];
|
||||
}
|
||||
@@ -282,12 +315,12 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
|
||||
|
||||
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url];
|
||||
mutableRequest.HTTPMethod = method;
|
||||
mutableRequest.allowsCellularAccess = self.allowsCellularAccess;
|
||||
mutableRequest.cachePolicy = self.cachePolicy;
|
||||
mutableRequest.HTTPShouldHandleCookies = self.HTTPShouldHandleCookies;
|
||||
mutableRequest.HTTPShouldUsePipelining = self.HTTPShouldUsePipelining;
|
||||
mutableRequest.networkServiceType = self.networkServiceType;
|
||||
mutableRequest.timeoutInterval = self.timeoutInterval;
|
||||
|
||||
for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
|
||||
if ([self.mutableObservedChangedKeyPaths containsObject:keyPath]) {
|
||||
[mutableRequest setValue:[self valueForKeyPath:keyPath] forKey:keyPath];
|
||||
}
|
||||
}
|
||||
|
||||
mutableRequest = [[self requestBySerializingRequest:mutableRequest withParameters:parameters error:error] mutableCopy];
|
||||
|
||||
@@ -341,8 +374,7 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
|
||||
|
||||
- (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request
|
||||
writingStreamContentsToFile:(NSURL *)fileURL
|
||||
completionHandler:(void (^)(NSError *error))handler;
|
||||
|
||||
completionHandler:(void (^)(NSError *error))handler
|
||||
{
|
||||
if (!request.HTTPBodyStream) {
|
||||
return [request mutableCopy];
|
||||
@@ -413,33 +445,61 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
|
||||
}
|
||||
}];
|
||||
|
||||
if (!parameters) {
|
||||
return mutableRequest;
|
||||
}
|
||||
if (parameters) {
|
||||
NSString *query = nil;
|
||||
if (self.queryStringSerialization) {
|
||||
NSError *serializationError;
|
||||
query = self.queryStringSerialization(request, parameters, &serializationError);
|
||||
|
||||
NSString *query = nil;
|
||||
if (self.queryStringSerialization) {
|
||||
query = self.queryStringSerialization(request, parameters, error);
|
||||
} else {
|
||||
switch (self.queryStringSerializationStyle) {
|
||||
case AFHTTPRequestQueryStringDefaultStyle:
|
||||
query = AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding);
|
||||
break;
|
||||
if (serializationError) {
|
||||
if (error) {
|
||||
*error = serializationError;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
} else {
|
||||
switch (self.queryStringSerializationStyle) {
|
||||
case AFHTTPRequestQueryStringDefaultStyle:
|
||||
query = AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
|
||||
mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]];
|
||||
} else {
|
||||
NSString *charset = (__bridge NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(self.stringEncoding));
|
||||
[mutableRequest setValue:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
|
||||
[mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];
|
||||
if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
|
||||
mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]];
|
||||
} else {
|
||||
if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
|
||||
[mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
|
||||
}
|
||||
[mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];
|
||||
}
|
||||
}
|
||||
|
||||
return mutableRequest;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSKeyValueObserving
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(__unused id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
if (context == AFHTTPRequestSerializerObserverContext) {
|
||||
if ([change[NSKeyValueChangeNewKey] isEqual:[NSNull null]]) {
|
||||
[self.mutableObservedChangedKeyPaths removeObject:keyPath];
|
||||
} else {
|
||||
[self.mutableObservedChangedKeyPaths addObject:keyPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [self init];
|
||||
@@ -447,8 +507,8 @@ NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.mutableHTTPRequestHeaders = [decoder decodeObjectForKey:NSStringFromSelector(@selector(mutableHTTPRequestHeaders))];
|
||||
self.queryStringSerializationStyle = (AFHTTPRequestQueryStringSerializationStyle)[decoder decodeIntegerForKey:NSStringFromSelector(@selector(queryStringSerializationStyle))];
|
||||
self.mutableHTTPRequestHeaders = [[decoder decodeObjectOfClass:[NSDictionary class] forKey:NSStringFromSelector(@selector(mutableHTTPRequestHeaders))] mutableCopy];
|
||||
self.queryStringSerializationStyle = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(queryStringSerializationStyle))] unsignedIntegerValue];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -514,14 +574,14 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
@property (nonatomic, strong) NSDictionary *headers;
|
||||
@property (nonatomic, copy) NSString *boundary;
|
||||
@property (nonatomic, strong) id body;
|
||||
@property (nonatomic, assign) NSUInteger bodyContentLength;
|
||||
@property (nonatomic, assign) unsigned long long bodyContentLength;
|
||||
@property (nonatomic, strong) NSInputStream *inputStream;
|
||||
|
||||
@property (nonatomic, assign) BOOL hasInitialBoundary;
|
||||
@property (nonatomic, assign) BOOL hasFinalBoundary;
|
||||
|
||||
@property (readonly, nonatomic, assign, getter = hasBytesAvailable) BOOL bytesAvailable;
|
||||
@property (readonly, nonatomic, assign) NSUInteger contentLength;
|
||||
@property (readonly, nonatomic, assign) unsigned long long contentLength;
|
||||
|
||||
- (NSInteger)read:(uint8_t *)buffer
|
||||
maxLength:(NSUInteger)length;
|
||||
@@ -531,8 +591,8 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
@property (nonatomic, assign) NSUInteger numberOfBytesInPacket;
|
||||
@property (nonatomic, assign) NSTimeInterval delay;
|
||||
@property (nonatomic, strong) NSInputStream *inputStream;
|
||||
@property (nonatomic, readonly, assign) NSUInteger contentLength;
|
||||
@property (nonatomic, readonly, assign, getter = isEmpty) BOOL empty;
|
||||
@property (readonly, nonatomic, assign) unsigned long long contentLength;
|
||||
@property (readonly, nonatomic, assign, getter = isEmpty) BOOL empty;
|
||||
|
||||
- (id)initWithStringEncoding:(NSStringEncoding)encoding;
|
||||
- (void)setInitialAndFinalBoundaries;
|
||||
@@ -591,16 +651,16 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
NSParameterAssert(mimeType);
|
||||
|
||||
if (![fileURL isFileURL]) {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedStringFromTable(@"Expected URL to be a file URL", @"AFNetworking", nil) forKey:NSLocalizedFailureReasonErrorKey];
|
||||
NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: NSLocalizedStringFromTable(@"Expected URL to be a file URL", @"AFNetworking", nil)};
|
||||
if (error) {
|
||||
*error = [[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadURL userInfo:userInfo];
|
||||
*error = [[NSError alloc] initWithDomain:AFURLRequestSerializationErrorDomain code:NSURLErrorBadURL userInfo:userInfo];
|
||||
}
|
||||
|
||||
return NO;
|
||||
} else if ([fileURL checkResourceIsReachableAndReturnError:error] == NO) {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:NSLocalizedStringFromTable(@"File URL not reachable.", @"AFNetworking", nil) forKey:NSLocalizedFailureReasonErrorKey];
|
||||
NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: NSLocalizedStringFromTable(@"File URL not reachable.", @"AFNetworking", nil)};
|
||||
if (error) {
|
||||
*error = [[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadURL userInfo:userInfo];
|
||||
*error = [[NSError alloc] initWithDomain:AFURLRequestSerializationErrorDomain code:NSURLErrorBadURL userInfo:userInfo];
|
||||
}
|
||||
|
||||
return NO;
|
||||
@@ -620,7 +680,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
bodyPart.headers = mutableHeaders;
|
||||
bodyPart.boundary = self.boundary;
|
||||
bodyPart.body = fileURL;
|
||||
bodyPart.bodyContentLength = [[fileAttributes objectForKey:NSFileSize] unsignedIntegerValue];
|
||||
bodyPart.bodyContentLength = [[fileAttributes objectForKey:NSFileSize] unsignedLongLongValue];
|
||||
[self.bodyStream appendHTTPBodyPart:bodyPart];
|
||||
|
||||
return YES;
|
||||
@@ -629,7 +689,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
- (void)appendPartWithInputStream:(NSInputStream *)inputStream
|
||||
name:(NSString *)name
|
||||
fileName:(NSString *)fileName
|
||||
length:(NSUInteger)length
|
||||
length:(int64_t)length
|
||||
mimeType:(NSString *)mimeType
|
||||
{
|
||||
NSParameterAssert(name);
|
||||
@@ -640,13 +700,13 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
[mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"];
|
||||
[mutableHeaders setValue:mimeType forKey:@"Content-Type"];
|
||||
|
||||
|
||||
AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init];
|
||||
bodyPart.stringEncoding = self.stringEncoding;
|
||||
bodyPart.headers = mutableHeaders;
|
||||
bodyPart.boundary = self.boundary;
|
||||
bodyPart.body = inputStream;
|
||||
bodyPart.bodyContentLength = length;
|
||||
|
||||
bodyPart.bodyContentLength = (unsigned long long)length;
|
||||
|
||||
[self.bodyStream appendHTTPBodyPart:bodyPart];
|
||||
}
|
||||
@@ -710,7 +770,7 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
[self.request setHTTPBodyStream:self.bodyStream];
|
||||
|
||||
[self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"];
|
||||
[self.request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"];
|
||||
[self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"];
|
||||
|
||||
return self.request;
|
||||
}
|
||||
@@ -719,9 +779,12 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface NSStream ()
|
||||
@property (readwrite) NSStreamStatus streamStatus;
|
||||
@property (readwrite, copy) NSError *streamError;
|
||||
@end
|
||||
|
||||
@interface AFMultipartBodyStream () <NSCopying>
|
||||
@property (readwrite, nonatomic, assign) NSStreamStatus streamStatus;
|
||||
@property (readwrite, nonatomic, strong) NSError *streamError;
|
||||
@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;
|
||||
@property (readwrite, nonatomic, strong) NSMutableArray *HTTPBodyParts;
|
||||
@property (readwrite, nonatomic, strong) NSEnumerator *HTTPBodyPartEnumerator;
|
||||
@@ -731,6 +794,14 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
@end
|
||||
|
||||
@implementation AFMultipartBodyStream
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wimplicit-atomic-properties"
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1100)
|
||||
@synthesize delegate;
|
||||
#endif
|
||||
@synthesize streamStatus;
|
||||
@synthesize streamError;
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
- (id)initWithStringEncoding:(NSStringEncoding)encoding {
|
||||
self = [super init];
|
||||
@@ -848,8 +919,8 @@ NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2;
|
||||
forMode:(__unused NSString *)mode
|
||||
{}
|
||||
|
||||
- (NSUInteger)contentLength {
|
||||
NSUInteger length = 0;
|
||||
- (unsigned long long)contentLength {
|
||||
unsigned long long length = 0;
|
||||
for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) {
|
||||
length += [bodyPart contentLength];
|
||||
}
|
||||
@@ -901,7 +972,7 @@ typedef enum {
|
||||
@interface AFHTTPBodyPart () <NSCopying> {
|
||||
AFHTTPBodyPartReadPhase _phase;
|
||||
NSInputStream *_inputStream;
|
||||
NSUInteger _phaseReadOffset;
|
||||
unsigned long long _phaseReadOffset;
|
||||
}
|
||||
|
||||
- (BOOL)transitionToNextPhase;
|
||||
@@ -938,6 +1009,8 @@ typedef enum {
|
||||
_inputStream = [NSInputStream inputStreamWithURL:self.body];
|
||||
} else if ([self.body isKindOfClass:[NSInputStream class]]) {
|
||||
_inputStream = self.body;
|
||||
} else {
|
||||
_inputStream = [NSInputStream inputStreamWithData:[NSData data]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -954,8 +1027,8 @@ typedef enum {
|
||||
return [NSString stringWithString:headerString];
|
||||
}
|
||||
|
||||
- (NSUInteger)contentLength {
|
||||
NSUInteger length = 0;
|
||||
- (unsigned long long)contentLength {
|
||||
unsigned long long length = 0;
|
||||
|
||||
NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding];
|
||||
length += [encapsulationBoundaryData length];
|
||||
@@ -1039,13 +1112,13 @@ typedef enum {
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgnu"
|
||||
NSRange range = NSMakeRange(_phaseReadOffset, MIN([data length] - _phaseReadOffset, length));
|
||||
NSRange range = NSMakeRange((NSUInteger)_phaseReadOffset, MIN([data length] - ((NSUInteger)_phaseReadOffset), length));
|
||||
[data getBytes:buffer range:range];
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
_phaseReadOffset += range.length;
|
||||
|
||||
if (_phaseReadOffset >= [data length]) {
|
||||
if (((NSUInteger)_phaseReadOffset) >= [data length]) {
|
||||
[self transitionToNextPhase];
|
||||
}
|
||||
|
||||
@@ -1093,6 +1166,7 @@ typedef enum {
|
||||
bodyPart.headers = self.headers;
|
||||
bodyPart.bodyContentLength = self.bodyContentLength;
|
||||
bodyPart.body = self.body;
|
||||
bodyPart.boundary = self.boundary;
|
||||
|
||||
return bodyPart;
|
||||
}
|
||||
@@ -1104,7 +1178,7 @@ typedef enum {
|
||||
@implementation AFJSONRequestSerializer
|
||||
|
||||
+ (instancetype)serializer {
|
||||
return [self serializerWithWritingOptions:0];
|
||||
return [self serializerWithWritingOptions:(NSJSONWritingOptions)0];
|
||||
}
|
||||
|
||||
+ (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions
|
||||
@@ -1135,19 +1209,19 @@ typedef enum {
|
||||
}
|
||||
}];
|
||||
|
||||
if (!parameters) {
|
||||
return mutableRequest;
|
||||
if (parameters) {
|
||||
if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
|
||||
NSString *charset = (__bridge NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
|
||||
[mutableRequest setValue:[NSString stringWithFormat:@"application/json; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
|
||||
}
|
||||
|
||||
[mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]];
|
||||
}
|
||||
|
||||
NSString *charset = (__bridge NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
|
||||
|
||||
[mutableRequest setValue:[NSString stringWithFormat:@"application/json; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
|
||||
[mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]];
|
||||
|
||||
return mutableRequest;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
@@ -1155,7 +1229,7 @@ typedef enum {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.writingOptions = (NSJSONWritingOptions)[decoder decodeIntegerForKey:NSStringFromSelector(@selector(writingOptions))];
|
||||
self.writingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(writingOptions))] unsignedIntegerValue];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -1169,7 +1243,7 @@ typedef enum {
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
AFJSONRequestSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
AFJSONRequestSerializer *serializer = [super copyWithZone:zone];
|
||||
serializer.writingOptions = self.writingOptions;
|
||||
|
||||
return serializer;
|
||||
@@ -1215,15 +1289,19 @@ typedef enum {
|
||||
}
|
||||
}];
|
||||
|
||||
NSString *charset = (__bridge NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
|
||||
if (parameters) {
|
||||
if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
|
||||
NSString *charset = (__bridge NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
|
||||
[mutableRequest setValue:[NSString stringWithFormat:@"application/x-plist; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
|
||||
}
|
||||
|
||||
[mutableRequest setValue:[NSString stringWithFormat:@"application/x-plist; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
|
||||
[mutableRequest setHTTPBody:[NSPropertyListSerialization dataWithPropertyList:parameters format:self.format options:self.writeOptions error:error]];
|
||||
[mutableRequest setHTTPBody:[NSPropertyListSerialization dataWithPropertyList:parameters format:self.format options:self.writeOptions error:error]];
|
||||
}
|
||||
|
||||
return mutableRequest;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
@@ -1231,8 +1309,8 @@ typedef enum {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.format = (NSPropertyListFormat)[decoder decodeIntegerForKey:NSStringFromSelector(@selector(format))];
|
||||
self.writeOptions = (NSPropertyListWriteOptions)[decoder decodeIntegerForKey:NSStringFromSelector(@selector(writeOptions))];
|
||||
self.format = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue];
|
||||
self.writeOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(writeOptions))] unsignedIntegerValue];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -1241,13 +1319,13 @@ typedef enum {
|
||||
[super encodeWithCoder:coder];
|
||||
|
||||
[coder encodeInteger:self.format forKey:NSStringFromSelector(@selector(format))];
|
||||
[coder encodeInteger:(NSInteger)self.writeOptions forKey:NSStringFromSelector(@selector(writeOptions))];
|
||||
[coder encodeObject:@(self.writeOptions) forKey:NSStringFromSelector(@selector(writeOptions))];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
AFPropertyListRequestSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
AFPropertyListRequestSerializer *serializer = [super copyWithZone:zone];
|
||||
serializer.format = self.format;
|
||||
serializer.writeOptions = self.writeOptions;
|
||||
|
||||
|
||||
55
src/ios/AFNetworking/AFURLResponseSerialization.h
Executable file → Normal file
55
src/ios/AFNetworking/AFURLResponseSerialization.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFSerialization.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
For example, a JSON response serializer may check for an acceptable status code (`2XX` range) and content type (`application/json`), decoding a valid JSON response into an object.
|
||||
*/
|
||||
@protocol AFURLResponseSerialization <NSObject, NSCoding, NSCopying>
|
||||
@protocol AFURLResponseSerialization <NSObject, NSSecureCoding, NSCopying>
|
||||
|
||||
/**
|
||||
The response object decoded from the data associated with a specified response.
|
||||
@@ -73,12 +73,12 @@
|
||||
|
||||
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||
*/
|
||||
@property (nonatomic, strong) NSIndexSet *acceptableStatusCodes;
|
||||
@property (nonatomic, copy) NSIndexSet *acceptableStatusCodes;
|
||||
|
||||
/**
|
||||
The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation.
|
||||
*/
|
||||
@property (nonatomic, strong) NSSet *acceptableContentTypes;
|
||||
@property (nonatomic, copy) NSSet *acceptableContentTypes;
|
||||
|
||||
/**
|
||||
Validates the specified response and data.
|
||||
@@ -116,6 +116,11 @@
|
||||
*/
|
||||
@property (nonatomic, assign) NSJSONReadingOptions readingOptions;
|
||||
|
||||
/**
|
||||
Whether to remove keys with `NSNull` values from response JSON. Defaults to `NO`.
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL removesKeysWithNullValues;
|
||||
|
||||
/**
|
||||
Creates and returns a JSON serializer with specified reading and writing options.
|
||||
|
||||
@@ -245,7 +250,7 @@
|
||||
/**
|
||||
The component response serializers.
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSArray *responseSerializers;
|
||||
@property (readonly, nonatomic, copy) NSArray *responseSerializers;
|
||||
|
||||
/**
|
||||
Creates and returns a compound serializer comprised of the specified response serializers.
|
||||
@@ -255,3 +260,43 @@
|
||||
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers;
|
||||
|
||||
@end
|
||||
|
||||
///----------------
|
||||
/// @name Constants
|
||||
///----------------
|
||||
|
||||
/**
|
||||
## Error Domains
|
||||
|
||||
The following error domain is predefined.
|
||||
|
||||
- `NSString * const AFURLResponseSerializationErrorDomain`
|
||||
|
||||
### Constants
|
||||
|
||||
`AFURLResponseSerializationErrorDomain`
|
||||
AFURLResponseSerializer errors. Error codes for `AFURLResponseSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`.
|
||||
*/
|
||||
extern NSString * const AFURLResponseSerializationErrorDomain;
|
||||
|
||||
/**
|
||||
## User info dictionary keys
|
||||
|
||||
These keys may exist in the user info dictionary, in addition to those defined for NSError.
|
||||
|
||||
- `NSString * const AFNetworkingOperationFailingURLResponseErrorKey`
|
||||
- `NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey`
|
||||
|
||||
### Constants
|
||||
|
||||
`AFNetworkingOperationFailingURLResponseErrorKey`
|
||||
The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`.
|
||||
|
||||
`AFNetworkingOperationFailingURLResponseDataErrorKey`
|
||||
The corresponding value is an `NSData` containing the original data of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`.
|
||||
*/
|
||||
extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey;
|
||||
|
||||
extern NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey;
|
||||
|
||||
|
||||
|
||||
149
src/ios/AFNetworking/AFURLResponseSerialization.m
Executable file → Normal file
149
src/ios/AFNetworking/AFURLResponseSerialization.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFSerialization.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,15 +22,16 @@
|
||||
|
||||
#import "AFURLResponseSerialization.h"
|
||||
|
||||
extern NSString * const AFNetworkingErrorDomain;
|
||||
extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey;
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
#import <UIKit/UIKit.h>
|
||||
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
NSString * const AFURLResponseSerializationErrorDomain = @"com.alamofire.error.serialization.response";
|
||||
NSString * const AFNetworkingOperationFailingURLResponseErrorKey = @"com.alamofire.serialization.response.error.response";
|
||||
NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey = @"com.alamofire.serialization.response.error.data";
|
||||
|
||||
static NSError * AFErrorWithUnderlyingError(NSError *error, NSError *underlyingError) {
|
||||
if (!error) {
|
||||
return underlyingError;
|
||||
@@ -46,16 +47,41 @@ static NSError * AFErrorWithUnderlyingError(NSError *error, NSError *underlyingE
|
||||
return [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:mutableUserInfo];
|
||||
}
|
||||
|
||||
static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
if (error.code == code) {
|
||||
static BOOL AFErrorOrUnderlyingErrorHasCodeInDomain(NSError *error, NSInteger code, NSString *domain) {
|
||||
if ([error.domain isEqualToString:domain] && error.code == code) {
|
||||
return YES;
|
||||
} else if (error.userInfo[NSUnderlyingErrorKey]) {
|
||||
return AFErrorOrUnderlyingErrorHasCode(error.userInfo[NSUnderlyingErrorKey], code);
|
||||
return AFErrorOrUnderlyingErrorHasCodeInDomain(error.userInfo[NSUnderlyingErrorKey], code, domain);
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions) {
|
||||
if ([JSONObject isKindOfClass:[NSArray class]]) {
|
||||
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]];
|
||||
for (id value in (NSArray *)JSONObject) {
|
||||
[mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)];
|
||||
}
|
||||
|
||||
return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray];
|
||||
} else if ([JSONObject isKindOfClass:[NSDictionary class]]) {
|
||||
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject];
|
||||
for (id <NSCopying> key in [(NSDictionary *)JSONObject allKeys]) {
|
||||
id value = [(NSDictionary *)JSONObject objectForKey:key];
|
||||
if (!value || [value isEqual:[NSNull null]]) {
|
||||
[mutableDictionary removeObjectForKey:key];
|
||||
} else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
|
||||
[mutableDictionary setObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions) forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary];
|
||||
}
|
||||
|
||||
return JSONObject;
|
||||
}
|
||||
|
||||
@implementation AFHTTPResponseSerializer
|
||||
|
||||
+ (instancetype)serializer {
|
||||
@@ -88,26 +114,33 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]]) {
|
||||
if ([data length] > 0) {
|
||||
NSDictionary *userInfo = @{
|
||||
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]],
|
||||
NSURLErrorFailingURLErrorKey:[response URL],
|
||||
AFNetworkingOperationFailingURLResponseErrorKey: response
|
||||
};
|
||||
NSMutableDictionary *mutableUserInfo = [@{
|
||||
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]],
|
||||
NSURLErrorFailingURLErrorKey:[response URL],
|
||||
AFNetworkingOperationFailingURLResponseErrorKey: response,
|
||||
} mutableCopy];
|
||||
if (data) {
|
||||
mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data;
|
||||
}
|
||||
|
||||
validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo], validationError);
|
||||
validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:mutableUserInfo], validationError);
|
||||
}
|
||||
|
||||
responseIsValid = NO;
|
||||
}
|
||||
|
||||
if (self.acceptableStatusCodes && ![self.acceptableStatusCodes containsIndex:(NSUInteger)response.statusCode]) {
|
||||
NSDictionary *userInfo = @{
|
||||
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%lu)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (unsigned long)response.statusCode],
|
||||
NSURLErrorFailingURLErrorKey:[response URL],
|
||||
AFNetworkingOperationFailingURLResponseErrorKey: response
|
||||
};
|
||||
NSMutableDictionary *mutableUserInfo = [@{
|
||||
NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%ld)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (long)response.statusCode],
|
||||
NSURLErrorFailingURLErrorKey:[response URL],
|
||||
AFNetworkingOperationFailingURLResponseErrorKey: response,
|
||||
} mutableCopy];
|
||||
|
||||
validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo], validationError);
|
||||
if (data) {
|
||||
mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data;
|
||||
}
|
||||
|
||||
validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorBadServerResponse userInfo:mutableUserInfo], validationError);
|
||||
|
||||
responseIsValid = NO;
|
||||
}
|
||||
@@ -131,7 +164,11 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
return data;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [self init];
|
||||
@@ -139,8 +176,8 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.acceptableStatusCodes = [decoder decodeObjectForKey:NSStringFromSelector(@selector(acceptableStatusCodes))];
|
||||
self.acceptableContentTypes = [decoder decodeObjectForKey:NSStringFromSelector(@selector(acceptableContentTypes))];
|
||||
self.acceptableStatusCodes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableStatusCodes))];
|
||||
self.acceptableContentTypes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableContentTypes))];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -167,7 +204,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
@implementation AFJSONResponseSerializer
|
||||
|
||||
+ (instancetype)serializer {
|
||||
return [self serializerWithReadingOptions:0];
|
||||
return [self serializerWithReadingOptions:(NSJSONReadingOptions)0];
|
||||
}
|
||||
|
||||
+ (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions {
|
||||
@@ -195,7 +232,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
|
||||
if (AFErrorOrUnderlyingErrorHasCode(*error, NSURLErrorCannotDecodeContentData)) {
|
||||
if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
@@ -227,23 +264,27 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
}
|
||||
} else {
|
||||
NSDictionary *userInfo = @{
|
||||
NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", nil, @"AFNetworking"),
|
||||
NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", nil, @"AFNetworking"), responseString]
|
||||
NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", @"AFNetworking", nil),
|
||||
NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", @"AFNetworking", nil), responseString]
|
||||
};
|
||||
|
||||
serializationError = [NSError errorWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo];
|
||||
serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self.removesKeysWithNullValues && responseObject) {
|
||||
responseObject = AFJSONObjectByRemovingKeysWithNullValues(responseObject, self.readingOptions);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
*error = AFErrorWithUnderlyingError(serializationError, *error);;
|
||||
*error = AFErrorWithUnderlyingError(serializationError, *error);
|
||||
}
|
||||
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
@@ -251,7 +292,8 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.readingOptions = (NSJSONReadingOptions)[decoder decodeIntegerForKey:NSStringFromSelector(@selector(readingOptions))];
|
||||
self.readingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readingOptions))] unsignedIntegerValue];
|
||||
self.removesKeysWithNullValues = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(removesKeysWithNullValues))] boolValue];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -259,7 +301,8 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||
[super encodeWithCoder:coder];
|
||||
|
||||
[coder encodeInteger:self.readingOptions forKey:NSStringFromSelector(@selector(readingOptions))];
|
||||
[coder encodeObject:@(self.readingOptions) forKey:NSStringFromSelector(@selector(readingOptions))];
|
||||
[coder encodeObject:@(self.removesKeysWithNullValues) forKey:NSStringFromSelector(@selector(removesKeysWithNullValues))];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
@@ -267,6 +310,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
AFJSONResponseSerializer *serializer = [[[self class] allocWithZone:zone] init];
|
||||
serializer.readingOptions = self.readingOptions;
|
||||
serializer.removesKeysWithNullValues = self.removesKeysWithNullValues;
|
||||
|
||||
return serializer;
|
||||
}
|
||||
@@ -301,7 +345,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
|
||||
if (AFErrorOrUnderlyingErrorHasCode(*error, NSURLErrorCannotDecodeContentData)) {
|
||||
if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
@@ -346,7 +390,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
|
||||
if (AFErrorOrUnderlyingErrorHasCode(*error, NSURLErrorCannotDecodeContentData)) {
|
||||
if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
@@ -361,7 +405,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
return document;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
@@ -369,7 +413,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.options = [decoder decodeIntegerForKey:NSStringFromSelector(@selector(options))];
|
||||
self.options = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(options))] unsignedIntegerValue];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -377,7 +421,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||
[super encodeWithCoder:coder];
|
||||
|
||||
[coder encodeInteger:self.options forKey:NSStringFromSelector(@selector(options))];
|
||||
[coder encodeObject:@(self.options) forKey:NSStringFromSelector(@selector(options))];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
@@ -429,7 +473,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
|
||||
if (AFErrorOrUnderlyingErrorHasCode(*error, NSURLErrorCannotDecodeContentData)) {
|
||||
if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
@@ -448,7 +492,7 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
@@ -456,8 +500,8 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.format = (NSPropertyListFormat)[decoder decodeIntegerForKey:NSStringFromSelector(@selector(format))];
|
||||
self.readOptions = (NSPropertyListReadOptions)[decoder decodeIntegerForKey:NSStringFromSelector(@selector(readOptions))];
|
||||
self.format = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue];
|
||||
self.readOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readOptions))] unsignedIntegerValue];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -465,8 +509,8 @@ static BOOL AFErrorOrUnderlyingErrorHasCode(NSError *error, NSInteger code) {
|
||||
- (void)encodeWithCoder:(NSCoder *)coder {
|
||||
[super encodeWithCoder:coder];
|
||||
|
||||
[coder encodeInteger:self.format forKey:NSStringFromSelector(@selector(format))];
|
||||
[coder encodeInteger:(NSInteger)self.readOptions forKey:NSStringFromSelector(@selector(readOptions))];
|
||||
[coder encodeObject:@(self.format) forKey:NSStringFromSelector(@selector(format))];
|
||||
[coder encodeObject:@(self.readOptions) forKey:NSStringFromSelector(@selector(readOptions))];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
@@ -547,6 +591,8 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
|
||||
if (colorSpaceModel == kCGColorSpaceModelRGB) {
|
||||
uint32_t alpha = (bitmapInfo & kCGBitmapAlphaInfoMask);
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wassign-enum"
|
||||
if (alpha == kCGImageAlphaNone) {
|
||||
bitmapInfo &= ~kCGBitmapAlphaInfoMask;
|
||||
bitmapInfo |= kCGImageAlphaNoneSkipFirst;
|
||||
@@ -554,6 +600,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
bitmapInfo &= ~kCGBitmapAlphaInfoMask;
|
||||
bitmapInfo |= kCGImageAlphaPremultipliedFirst;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
CGContextRef context = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);
|
||||
@@ -606,7 +653,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
error:(NSError *__autoreleasing *)error
|
||||
{
|
||||
if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
|
||||
if (AFErrorOrUnderlyingErrorHasCode(*error, NSURLErrorCannotDecodeContentData)) {
|
||||
if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
@@ -629,7 +676,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
@@ -638,7 +685,13 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
||||
self.imageScale = [[decoder decodeObjectForKey:NSStringFromSelector(@selector(imageScale))] floatValue];
|
||||
NSNumber *imageScale = [decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(imageScale))];
|
||||
#if CGFLOAT_IS_DOUBLE
|
||||
self.imageScale = [imageScale doubleValue];
|
||||
#else
|
||||
self.imageScale = [imageScale floatValue];
|
||||
#endif
|
||||
|
||||
self.automaticallyInflatesResponseImage = [decoder decodeBoolForKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))];
|
||||
#endif
|
||||
|
||||
@@ -672,7 +725,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
#pragma mark -
|
||||
|
||||
@interface AFCompoundResponseSerializer ()
|
||||
@property (readwrite, nonatomic, strong) NSArray *responseSerializers;
|
||||
@property (readwrite, nonatomic, copy) NSArray *responseSerializers;
|
||||
@end
|
||||
|
||||
@implementation AFCompoundResponseSerializer
|
||||
@@ -709,7 +762,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
return [super responseObjectForResponse:response data:data error:error];
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
self = [super initWithCoder:decoder];
|
||||
@@ -717,7 +770,7 @@ static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *r
|
||||
return nil;
|
||||
}
|
||||
|
||||
self.responseSerializers = [decoder decodeObjectForKey:NSStringFromSelector(@selector(responseSerializers))];
|
||||
self.responseSerializers = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(responseSerializers))];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
49
src/ios/AFNetworking/AFURLSessionManager.h
Executable file → Normal file
49
src/ios/AFNetworking/AFURLSessionManager.h
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFURLSessionManager.h
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
- `URLSession:didBecomeInvalidWithError:`
|
||||
- `URLSession:didReceiveChallenge:completionHandler:`
|
||||
- `URLSessionDidFinishEventsForBackgroundURLSession:`
|
||||
|
||||
### `NSURLSessionTaskDelegate`
|
||||
|
||||
@@ -56,7 +57,6 @@
|
||||
- `URLSession:dataTask:didBecomeDownloadTask:`
|
||||
- `URLSession:dataTask:didReceiveData:`
|
||||
- `URLSession:dataTask:willCacheResponse:completionHandler:`
|
||||
- `URLSessionDidFinishEventsForBackgroundURLSession:`
|
||||
|
||||
### `NSURLSessionDownloadDelegate`
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090)
|
||||
|
||||
@interface AFURLSessionManager : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate, NSCoding, NSCopying>
|
||||
@interface AFURLSessionManager : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate, NSSecureCoding, NSCopying>
|
||||
|
||||
/**
|
||||
The managed session.
|
||||
@@ -143,9 +143,9 @@
|
||||
*/
|
||||
@property (readonly, nonatomic, strong) NSArray *downloadTasks;
|
||||
|
||||
///---------------------------------
|
||||
///-------------------------------
|
||||
/// @name Managing Callback Queues
|
||||
///---------------------------------
|
||||
///-------------------------------
|
||||
|
||||
/**
|
||||
The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used.
|
||||
@@ -157,6 +157,19 @@
|
||||
*/
|
||||
@property (nonatomic, strong) dispatch_group_t completionGroup;
|
||||
|
||||
///---------------------------------
|
||||
/// @name Working Around System Bugs
|
||||
///---------------------------------
|
||||
|
||||
/**
|
||||
Whether to attempt to retry creation of upload tasks for background sessions when initial call returns `nil`. `NO` by default.
|
||||
|
||||
@bug As of iOS 7.0, there is a bug where upload tasks created for background tasks are sometimes `nil`. As a workaround, if this property is `YES`, AFNetworking will follow Apple's recommendation to try creating the task again.
|
||||
|
||||
@see https://github.com/AFNetworking/AFNetworking/issues/1675
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL attemptsToRecreateUploadTasksForBackgroundSessions;
|
||||
|
||||
///---------------------
|
||||
/// @name Initialization
|
||||
///---------------------
|
||||
@@ -201,6 +214,8 @@
|
||||
@param fileURL A URL to the local file to be uploaded.
|
||||
@param progress A progress object monitoring the current upload progress.
|
||||
@param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any.
|
||||
|
||||
@see `attemptsToRecreateUploadTasksForBackgroundSessions`
|
||||
*/
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
|
||||
fromFile:(NSURL *)fileURL
|
||||
@@ -242,6 +257,8 @@
|
||||
@param progress A progress object monitoring the current download progress.
|
||||
@param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL.
|
||||
@param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any.
|
||||
|
||||
@warning If using a background `NSURLSessionConfiguration` on iOS, these blocks will be lost when the app is terminated. Background sessions may prefer to use `-setDownloadTaskDidFinishDownloadingBlock:` to specify the URL for saving the downloaded file, rather than the destination block of this method.
|
||||
*/
|
||||
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
@@ -261,6 +278,28 @@
|
||||
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler;
|
||||
|
||||
///---------------------------------
|
||||
/// @name Getting Progress for Tasks
|
||||
///---------------------------------
|
||||
|
||||
/**
|
||||
Returns the upload progress of the specified task.
|
||||
|
||||
@param uploadTask The session upload task. Must not be `nil`.
|
||||
|
||||
@return An `NSProgress` object reporting the upload progress of a task, or `nil` if the progress is unavailable.
|
||||
*/
|
||||
- (NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask;
|
||||
|
||||
/**
|
||||
Returns the download progress of the specified task.
|
||||
|
||||
@param downloadTask The session download task. Must not be `nil`.
|
||||
|
||||
@return An `NSProgress` object reporting the download progress of a task, or `nil` if the progress is unavailable.
|
||||
*/
|
||||
- (NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask;
|
||||
|
||||
///-----------------------------------------
|
||||
/// @name Setting Session Delegate Callbacks
|
||||
///-----------------------------------------
|
||||
|
||||
448
src/ios/AFNetworking/AFURLSessionManager.m
Executable file → Normal file
448
src/ios/AFNetworking/AFURLSessionManager.m
Executable file → Normal file
@@ -1,6 +1,6 @@
|
||||
// AFURLSessionManager.m
|
||||
//
|
||||
// Copyright (c) 2013 AFNetworking (http://afnetworking.com)
|
||||
// Copyright (c) 2013-2014 AFNetworking (http://afnetworking.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,6 +24,16 @@
|
||||
|
||||
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090)
|
||||
|
||||
static dispatch_queue_t url_session_manager_creation_queue() {
|
||||
static dispatch_queue_t af_url_session_manager_creation_queue;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
af_url_session_manager_creation_queue = dispatch_queue_create("com.alamofire.networking.session.manager.creation", DISPATCH_QUEUE_SERIAL);
|
||||
});
|
||||
|
||||
return af_url_session_manager_creation_queue;
|
||||
}
|
||||
|
||||
static dispatch_queue_t url_session_manager_processing_queue() {
|
||||
static dispatch_queue_t af_url_session_manager_processing_queue;
|
||||
static dispatch_once_t onceToken;
|
||||
@@ -67,6 +77,8 @@ NSString * const AFNetworkingTaskDidFinishAssetPathKey = @"com.alamofire.network
|
||||
|
||||
static NSString * const AFURLSessionManagerLockName = @"com.alamofire.networking.session.manager.lock";
|
||||
|
||||
static NSUInteger const AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask = 3;
|
||||
|
||||
static void * AFTaskStateChangedContext = &AFTaskStateChangedContext;
|
||||
|
||||
typedef void (^AFURLSessionDidBecomeInvalidBlock)(NSURLSession *session, NSError *error);
|
||||
@@ -74,6 +86,7 @@ typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionDidReceiveAuthenticat
|
||||
|
||||
typedef NSURLRequest * (^AFURLSessionTaskWillPerformHTTPRedirectionBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request);
|
||||
typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionTaskDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential);
|
||||
typedef void (^AFURLSessionDidFinishEventsForBackgroundURLSessionBlock)(NSURLSession *session);
|
||||
|
||||
typedef NSInputStream * (^AFURLSessionTaskNeedNewBodyStreamBlock)(NSURLSession *session, NSURLSessionTask *task);
|
||||
typedef void (^AFURLSessionTaskDidSendBodyDataBlock)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend);
|
||||
@@ -83,7 +96,6 @@ typedef NSURLSessionResponseDisposition (^AFURLSessionDataTaskDidReceiveResponse
|
||||
typedef void (^AFURLSessionDataTaskDidBecomeDownloadTaskBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask);
|
||||
typedef void (^AFURLSessionDataTaskDidReceiveDataBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data);
|
||||
typedef NSCachedURLResponse * (^AFURLSessionDataTaskWillCacheResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse);
|
||||
typedef void (^AFURLSessionDidFinishEventsForBackgroundURLSessionBlock)(NSURLSession *session);
|
||||
|
||||
typedef NSURL * (^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location);
|
||||
typedef void (^AFURLSessionDownloadTaskDidWriteDataBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite);
|
||||
@@ -95,32 +107,15 @@ typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id re
|
||||
|
||||
@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
|
||||
@property (nonatomic, weak) AFURLSessionManager *manager;
|
||||
@property (nonatomic, strong) id <AFURLResponseSerialization> responseSerializer;
|
||||
@property (nonatomic, strong) NSMutableData *mutableData;
|
||||
@property (nonatomic, strong) NSProgress *uploadProgress;
|
||||
@property (nonatomic, strong) NSProgress *downloadProgress;
|
||||
@property (nonatomic, strong) NSProgress *progress;
|
||||
@property (nonatomic, copy) NSURL *downloadFileURL;
|
||||
@property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading;
|
||||
@property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler;
|
||||
|
||||
+ (instancetype)delegateForManager:(AFURLSessionManager *)manager
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AFURLSessionManagerTaskDelegate
|
||||
|
||||
+ (instancetype)delegateForManager:(AFURLSessionManager *)manager
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [[self alloc] init];
|
||||
delegate.manager = manager;
|
||||
delegate.responseSerializer = manager.responseSerializer;
|
||||
delegate.completionHandler = completionHandler;
|
||||
|
||||
return delegate;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
@@ -129,8 +124,7 @@ typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id re
|
||||
|
||||
self.mutableData = [NSMutableData data];
|
||||
|
||||
self.uploadProgress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
|
||||
self.downloadProgress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
|
||||
self.progress = [NSProgress progressWithTotalUnitCount:0];
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -143,15 +137,8 @@ typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id re
|
||||
totalBytesSent:(int64_t)totalBytesSent
|
||||
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
|
||||
{
|
||||
int64_t totalUnitCount = totalBytesExpectedToSend;
|
||||
if(totalUnitCount == NSURLSessionTransferSizeUnknown) {
|
||||
NSString *contentLength = [task.originalRequest valueForHTTPHeaderField:@"Content-Length"];
|
||||
if(contentLength) {
|
||||
totalUnitCount = (int64_t) [contentLength longLongValue];
|
||||
}
|
||||
}
|
||||
self.uploadProgress.totalUnitCount = totalUnitCount;
|
||||
self.uploadProgress.completedUnitCount = totalBytesSent;
|
||||
self.progress.totalUnitCount = totalBytesExpectedToSend;
|
||||
self.progress.completedUnitCount = totalBytesSent;
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
@@ -165,7 +152,7 @@ didCompleteWithError:(NSError *)error
|
||||
__block id responseObject = nil;
|
||||
|
||||
__block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
|
||||
userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = self.responseSerializer;
|
||||
userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;
|
||||
|
||||
if (self.downloadFileURL) {
|
||||
userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;
|
||||
@@ -188,7 +175,7 @@ didCompleteWithError:(NSError *)error
|
||||
} else {
|
||||
dispatch_async(url_session_manager_processing_queue(), ^{
|
||||
NSError *serializationError = nil;
|
||||
responseObject = [self.responseSerializer responseObjectForResponse:task.response data:[NSData dataWithData:self.mutableData] error:&serializationError];
|
||||
responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:[NSData dataWithData:self.mutableData] error:&serializationError];
|
||||
|
||||
if (self.downloadFileURL) {
|
||||
responseObject = self.downloadFileURL;
|
||||
@@ -223,8 +210,6 @@ didCompleteWithError:(NSError *)error
|
||||
didReceiveData:(NSData *)data
|
||||
{
|
||||
[self.mutableData appendData:data];
|
||||
|
||||
self.downloadProgress.completedUnitCount += (int64_t)[data length];
|
||||
}
|
||||
|
||||
#pragma mark - NSURLSessionDownloadTaskDelegate
|
||||
@@ -254,16 +239,16 @@ didFinishDownloadingToURL:(NSURL *)location
|
||||
totalBytesWritten:(int64_t)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
|
||||
{
|
||||
self.downloadProgress.totalUnitCount = totalBytesExpectedToWrite;
|
||||
self.downloadProgress.completedUnitCount = totalBytesWritten;
|
||||
self.progress.totalUnitCount = totalBytesExpectedToWrite;
|
||||
self.progress.completedUnitCount = totalBytesWritten;
|
||||
}
|
||||
|
||||
- (void)URLSession:(__unused NSURLSession *)session
|
||||
downloadTask:(__unused NSURLSessionDownloadTask *)downloadTask
|
||||
didResumeAtOffset:(int64_t)fileOffset
|
||||
expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
self.downloadProgress.totalUnitCount = expectedTotalBytes;
|
||||
self.downloadProgress.completedUnitCount = fileOffset;
|
||||
self.progress.totalUnitCount = expectedTotalBytes;
|
||||
self.progress.completedUnitCount = fileOffset;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -278,6 +263,7 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
@property (readwrite, nonatomic, strong) NSLock *lock;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDidBecomeInvalidBlock sessionDidBecomeInvalid;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDidReceiveAuthenticationChallengeBlock sessionDidReceiveAuthenticationChallenge;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDidFinishEventsForBackgroundURLSessionBlock didFinishEventsForBackgroundURLSession;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionTaskWillPerformHTTPRedirectionBlock taskWillPerformHTTPRedirection;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionTaskDidReceiveAuthenticationChallengeBlock taskDidReceiveAuthenticationChallenge;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionTaskNeedNewBodyStreamBlock taskNeedNewBodyStream;
|
||||
@@ -287,7 +273,6 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidBecomeDownloadTaskBlock dataTaskDidBecomeDownloadTask;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveDataBlock dataTaskDidReceiveData;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDataTaskWillCacheResponseBlock dataTaskWillCacheResponse;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDidFinishEventsForBackgroundURLSessionBlock didFinishEventsForBackgroundURLSession;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidWriteDataBlock downloadTaskDidWriteData;
|
||||
@property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidResumeBlock downloadTaskDidResume;
|
||||
@@ -309,30 +294,41 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
}
|
||||
|
||||
self.operationQueue = [[NSOperationQueue alloc] init];
|
||||
self.operationQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;
|
||||
|
||||
self.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
|
||||
self.sessionConfiguration = configuration;
|
||||
|
||||
self.operationQueue = [[NSOperationQueue alloc] init];
|
||||
self.operationQueue.maxConcurrentOperationCount = 1;
|
||||
|
||||
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
|
||||
|
||||
self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
|
||||
self.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
|
||||
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
|
||||
|
||||
self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
|
||||
|
||||
self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
|
||||
|
||||
self.lock = [[NSLock alloc] init];
|
||||
self.lock.name = AFURLSessionManagerLockName;
|
||||
|
||||
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
|
||||
for (NSURLSessionDataTask *task in dataTasks) {
|
||||
[self addDelegateForDataTask:task completionHandler:nil];
|
||||
}
|
||||
|
||||
for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
|
||||
[self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
|
||||
}
|
||||
|
||||
for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
|
||||
[self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
|
||||
}
|
||||
}];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, self.session, self.operationQueue];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task {
|
||||
@@ -352,17 +348,80 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
NSParameterAssert(task);
|
||||
NSParameterAssert(delegate);
|
||||
|
||||
[task addObserver:self forKeyPath:NSStringFromSelector(@selector(state)) options:(NSKeyValueObservingOptions)(NSKeyValueObservingOptionOld |NSKeyValueObservingOptionNew) context:AFTaskStateChangedContext];
|
||||
[self.lock lock];
|
||||
[task addObserver:self forKeyPath:NSStringFromSelector(@selector(state)) options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:AFTaskStateChangedContext];
|
||||
self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
|
||||
[self.lock unlock];
|
||||
}
|
||||
|
||||
- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
|
||||
delegate.manager = self;
|
||||
delegate.completionHandler = completionHandler;
|
||||
|
||||
[self setDelegate:delegate forTask:dataTask];
|
||||
}
|
||||
|
||||
- (void)addDelegateForUploadTask:(NSURLSessionUploadTask *)uploadTask
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
|
||||
delegate.manager = self;
|
||||
delegate.completionHandler = completionHandler;
|
||||
|
||||
int64_t totalUnitCount = uploadTask.countOfBytesExpectedToSend;
|
||||
if(totalUnitCount == NSURLSessionTransferSizeUnknown) {
|
||||
NSString *contentLength = [uploadTask.originalRequest valueForHTTPHeaderField:@"Content-Length"];
|
||||
if(contentLength) {
|
||||
totalUnitCount = (int64_t) [contentLength longLongValue];
|
||||
}
|
||||
}
|
||||
|
||||
delegate.progress = [NSProgress progressWithTotalUnitCount:totalUnitCount];
|
||||
delegate.progress.pausingHandler = ^{
|
||||
[uploadTask suspend];
|
||||
};
|
||||
delegate.progress.cancellationHandler = ^{
|
||||
[uploadTask cancel];
|
||||
};
|
||||
|
||||
if (progress) {
|
||||
*progress = delegate.progress;
|
||||
}
|
||||
|
||||
[self setDelegate:delegate forTask:uploadTask];
|
||||
}
|
||||
|
||||
- (void)addDelegateForDownloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
|
||||
delegate.manager = self;
|
||||
delegate.completionHandler = completionHandler;
|
||||
|
||||
if (destination) {
|
||||
delegate.downloadTaskDidFinishDownloading = ^NSURL * (NSURLSession * __unused session, NSURLSessionDownloadTask *task, NSURL *location) {
|
||||
return destination(location, task.response);
|
||||
};
|
||||
}
|
||||
|
||||
if (progress) {
|
||||
*progress = delegate.progress;
|
||||
}
|
||||
|
||||
[self setDelegate:delegate forTask:downloadTask];
|
||||
}
|
||||
|
||||
- (void)removeDelegateForTask:(NSURLSessionTask *)task {
|
||||
NSParameterAssert(task);
|
||||
|
||||
[self.lock lock];
|
||||
[task removeObserver:self forKeyPath:NSStringFromSelector(@selector(state)) context:AFTaskStateChangedContext];
|
||||
[self.lock lock];
|
||||
[self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)];
|
||||
[self.lock unlock];
|
||||
}
|
||||
@@ -416,11 +475,13 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
#pragma mark -
|
||||
|
||||
- (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks {
|
||||
if (cancelPendingTasks) {
|
||||
[self.session invalidateAndCancel];
|
||||
} else {
|
||||
[self.session finishTasksAndInvalidate];
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (cancelPendingTasks) {
|
||||
[self.session invalidateAndCancel];
|
||||
} else {
|
||||
[self.session finishTasksAndInvalidate];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
@@ -436,10 +497,12 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];
|
||||
__block NSURLSessionDataTask *dataTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
dataTask = [self.session dataTaskWithRequest:request];
|
||||
});
|
||||
|
||||
AFURLSessionManagerTaskDelegate *delegate = [AFURLSessionManagerTaskDelegate delegateForManager:self completionHandler:completionHandler];
|
||||
[self setDelegate:delegate forTask:dataTask];
|
||||
[self addDelegateForDataTask:dataTask completionHandler:completionHandler];
|
||||
|
||||
return dataTask;
|
||||
}
|
||||
@@ -451,9 +514,20 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL];
|
||||
__block NSURLSessionUploadTask *uploadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL];
|
||||
});
|
||||
|
||||
return [self uploadTaskWithTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
if (!uploadTask && self.attemptsToRecreateUploadTasksForBackgroundSessions && self.session.configuration.identifier) {
|
||||
for (NSUInteger attempts = 0; !uploadTask && attempts < AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask; attempts++) {
|
||||
uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL];
|
||||
}
|
||||
}
|
||||
|
||||
[self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
|
||||
return uploadTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
|
||||
@@ -461,50 +535,27 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithRequest:request fromData:bodyData];
|
||||
__block NSURLSessionUploadTask *uploadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
uploadTask = [self.session uploadTaskWithRequest:request fromData:bodyData];
|
||||
});
|
||||
|
||||
return [self uploadTaskWithTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
[self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
|
||||
return uploadTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithStreamedRequest:request];
|
||||
__block NSURLSessionUploadTask *uploadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
uploadTask = [self.session uploadTaskWithStreamedRequest:request];
|
||||
});
|
||||
|
||||
return [self uploadTaskWithTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
}
|
||||
[self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler];
|
||||
|
||||
- (NSURLSessionUploadTask *)uploadTaskWithTask:(NSURLSessionUploadTask *)uploadTask
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
|
||||
{
|
||||
NSParameterAssert(uploadTask);
|
||||
|
||||
AFURLSessionManagerTaskDelegate *delegate = [AFURLSessionManagerTaskDelegate delegateForManager:self completionHandler:completionHandler];
|
||||
|
||||
int64_t totalUnitCount = uploadTask.countOfBytesExpectedToSend;
|
||||
if(totalUnitCount == NSURLSessionTransferSizeUnknown) {
|
||||
NSString *contentLength = [uploadTask.originalRequest valueForHTTPHeaderField:@"Content-Length"];
|
||||
if(contentLength) {
|
||||
totalUnitCount = (int64_t) [contentLength longLongValue];
|
||||
}
|
||||
}
|
||||
|
||||
delegate.uploadProgress = [NSProgress progressWithTotalUnitCount:totalUnitCount];
|
||||
delegate.uploadProgress.pausingHandler = ^{
|
||||
[uploadTask suspend];
|
||||
};
|
||||
delegate.uploadProgress.cancellationHandler = ^{
|
||||
[uploadTask cancel];
|
||||
};
|
||||
|
||||
if (progress) {
|
||||
*progress = delegate.uploadProgress;
|
||||
}
|
||||
|
||||
[self setDelegate:delegate forTask:uploadTask];
|
||||
|
||||
return uploadTask;
|
||||
}
|
||||
|
||||
@@ -515,9 +566,14 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
|
||||
{
|
||||
NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];
|
||||
__block NSURLSessionDownloadTask *downloadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
downloadTask = [self.session downloadTaskWithRequest:request];
|
||||
});
|
||||
|
||||
return [self downloadTaskWithTask:downloadTask progress:progress destination:destination completionHandler:completionHandler];
|
||||
[self addDelegateForDownloadTask:downloadTask progress:progress destination:destination completionHandler:completionHandler];
|
||||
|
||||
return downloadTask;
|
||||
}
|
||||
|
||||
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
|
||||
@@ -525,38 +581,28 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
|
||||
{
|
||||
NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithResumeData:resumeData];
|
||||
__block NSURLSessionDownloadTask *downloadTask = nil;
|
||||
dispatch_sync(url_session_manager_creation_queue(), ^{
|
||||
downloadTask = [self.session downloadTaskWithResumeData:resumeData];
|
||||
});
|
||||
|
||||
return [self downloadTaskWithTask:downloadTask progress:progress destination:destination completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (NSURLSessionDownloadTask *)downloadTaskWithTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
progress:(NSProgress * __autoreleasing *)progress
|
||||
destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
|
||||
completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler
|
||||
{
|
||||
NSParameterAssert(downloadTask);
|
||||
|
||||
AFURLSessionManagerTaskDelegate *delegate = [AFURLSessionManagerTaskDelegate delegateForManager:self completionHandler:completionHandler];
|
||||
delegate.downloadTaskDidFinishDownloading = ^NSURL * (NSURLSession * __unused session, NSURLSessionDownloadTask *task, NSURL *location) {
|
||||
if (destination) {
|
||||
return destination(location, task.response);
|
||||
}
|
||||
|
||||
return location;
|
||||
};
|
||||
|
||||
if (progress) {
|
||||
*progress = delegate.downloadProgress;
|
||||
}
|
||||
|
||||
[self setDelegate:delegate forTask:downloadTask];
|
||||
[self addDelegateForDownloadTask:downloadTask progress:progress destination:destination completionHandler:completionHandler];
|
||||
|
||||
return downloadTask;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask {
|
||||
return [[self delegateForTask:uploadTask] progress];
|
||||
}
|
||||
|
||||
- (NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask {
|
||||
return [[self delegateForTask:downloadTask] progress];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setSessionDidBecomeInvalidBlock:(void (^)(NSURLSession *session, NSError *error))block {
|
||||
self.sessionDidBecomeInvalid = block;
|
||||
}
|
||||
@@ -565,10 +611,14 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
self.sessionDidReceiveAuthenticationChallenge = block;
|
||||
}
|
||||
|
||||
- (void)setDidFinishEventsForBackgroundURLSessionBlock:(void (^)(NSURLSession *session))block {
|
||||
self.didFinishEventsForBackgroundURLSession = block;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setTaskNeedNewBodyStreamBlock:(NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block {
|
||||
self.taskNeedNewBodyStream = block;
|
||||
self.taskNeedNewBodyStream = block;
|
||||
}
|
||||
|
||||
- (void)setTaskWillPerformHTTPRedirectionBlock:(NSURLRequest * (^)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request))block {
|
||||
@@ -605,10 +655,6 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
self.dataTaskWillCacheResponse = block;
|
||||
}
|
||||
|
||||
- (void)setDidFinishEventsForBackgroundURLSessionBlock:(void (^)(NSURLSession *session))block {
|
||||
self.didFinishEventsForBackgroundURLSession = block;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setDownloadTaskDidFinishDownloadingBlock:(NSURL * (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block {
|
||||
@@ -623,6 +669,62 @@ expectedTotalBytes:(int64_t)expectedTotalBytes {
|
||||
self.downloadTaskDidResume = block;
|
||||
}
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"<%@: %p, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, self.session, self.operationQueue];
|
||||
}
|
||||
|
||||
- (BOOL)respondsToSelector:(SEL)selector {
|
||||
if (selector == @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:)) {
|
||||
return self.taskWillPerformHTTPRedirection != nil;
|
||||
} else if (selector == @selector(URLSession:dataTask:didReceiveResponse:completionHandler:)) {
|
||||
return self.dataTaskDidReceiveResponse != nil;
|
||||
} else if (selector == @selector(URLSession:dataTask:willCacheResponse:completionHandler:)) {
|
||||
return self.dataTaskWillCacheResponse != nil;
|
||||
} else if (selector == @selector(URLSessionDidFinishEventsForBackgroundURLSession:)) {
|
||||
return self.didFinishEventsForBackgroundURLSession != nil;
|
||||
}
|
||||
|
||||
return [[self class] instancesRespondToSelector:selector];
|
||||
}
|
||||
|
||||
#pragma mark - NSKeyValueObserving
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
if (context == AFTaskStateChangedContext && [keyPath isEqualToString:@"state"]) {
|
||||
if (change[NSKeyValueChangeOldKey] && change[NSKeyValueChangeNewKey] && [change[NSKeyValueChangeNewKey] isEqual:change[NSKeyValueChangeOldKey]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *notificationName = nil;
|
||||
switch ([(NSURLSessionTask *)object state]) {
|
||||
case NSURLSessionTaskStateRunning:
|
||||
notificationName = AFNetworkingTaskDidResumeNotification;
|
||||
break;
|
||||
case NSURLSessionTaskStateSuspended:
|
||||
notificationName = AFNetworkingTaskDidSuspendNotification;
|
||||
break;
|
||||
case NSURLSessionTaskStateCompleted:
|
||||
// AFNetworkingTaskDidFinishNotification posted by task completion handlers
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (notificationName) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:object];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - NSURLSessionDelegate
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session
|
||||
@@ -632,7 +734,14 @@ didBecomeInvalidWithError:(NSError *)error
|
||||
self.sessionDidBecomeInvalid(session, error);
|
||||
}
|
||||
|
||||
[self removeAllDelegates];
|
||||
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
|
||||
NSArray *tasks = [@[dataTasks, uploadTasks, downloadTasks] valueForKeyPath:@"@unionOfArrays.self"];
|
||||
for (NSURLSessionTask *task in tasks) {
|
||||
[task removeObserver:self forKeyPath:NSStringFromSelector(@selector(state)) context:AFTaskStateChangedContext];
|
||||
}
|
||||
|
||||
[self removeAllDelegates];
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDidInvalidateNotification object:session];
|
||||
}
|
||||
@@ -738,11 +847,20 @@ didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
|
||||
totalBytesSent:(int64_t)totalBytesSent
|
||||
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
|
||||
{
|
||||
|
||||
int64_t totalUnitCount = totalBytesExpectedToSend;
|
||||
if(totalUnitCount == NSURLSessionTransferSizeUnknown) {
|
||||
NSString *contentLength = [task.originalRequest valueForHTTPHeaderField:@"Content-Length"];
|
||||
if(contentLength) {
|
||||
totalUnitCount = (int64_t) [contentLength longLongValue];
|
||||
}
|
||||
}
|
||||
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
|
||||
[delegate URLSession:session task:task didSendBodyData:bytesSent totalBytesSent:totalBytesSent totalBytesExpectedToSend:totalBytesExpectedToSend];
|
||||
[delegate URLSession:session task:task didSendBodyData:bytesSent totalBytesSent:totalBytesSent totalBytesExpectedToSend:totalUnitCount];
|
||||
|
||||
if (self.taskDidSendBodyData) {
|
||||
self.taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend);
|
||||
self.taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalUnitCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -756,12 +874,13 @@ didCompleteWithError:(NSError *)error
|
||||
if (delegate) {
|
||||
[delegate URLSession:session task:task didCompleteWithError:error];
|
||||
|
||||
if (self.taskDidComplete) {
|
||||
self.taskDidComplete(session, task, error);
|
||||
}
|
||||
|
||||
[self removeDelegateForTask:task];
|
||||
}
|
||||
|
||||
if (self.taskDidComplete) {
|
||||
self.taskDidComplete(session, task, error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - NSURLSessionDataDelegate
|
||||
@@ -817,7 +936,7 @@ didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
NSCachedURLResponse *cachedResponse = proposedResponse;
|
||||
|
||||
if (self.dataTaskWillCacheResponse) {
|
||||
cachedResponse = self.dataTaskWillCacheResponse(session, dataTask, proposedResponse);
|
||||
cachedResponse = self.dataTaskWillCacheResponse(session, dataTask, proposedResponse);
|
||||
}
|
||||
|
||||
if (completionHandler) {
|
||||
@@ -827,7 +946,9 @@ didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
|
||||
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
|
||||
if (self.didFinishEventsForBackgroundURLSession) {
|
||||
self.didFinishEventsForBackgroundURLSession(session);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.didFinishEventsForBackgroundURLSession(session);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,10 +958,7 @@ didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
downloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
didFinishDownloadingToURL:(NSURL *)location
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask];
|
||||
if (delegate) {
|
||||
[delegate URLSession:session downloadTask:downloadTask didFinishDownloadingToURL:location];
|
||||
} else if (self.downloadTaskDidFinishDownloading) {
|
||||
if (self.downloadTaskDidFinishDownloading) {
|
||||
NSURL *fileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location);
|
||||
if (fileURL) {
|
||||
NSError *error = nil;
|
||||
@@ -848,8 +966,15 @@ didFinishDownloadingToURL:(NSURL *)location
|
||||
if (error) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:error.userInfo];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask];
|
||||
if (delegate) {
|
||||
[delegate URLSession:session downloadTask:downloadTask didFinishDownloadingToURL:location];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session
|
||||
@@ -871,47 +996,22 @@ totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
|
||||
didResumeAtOffset:(int64_t)fileOffset
|
||||
expectedTotalBytes:(int64_t)expectedTotalBytes
|
||||
{
|
||||
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask];
|
||||
[delegate URLSession:session downloadTask:downloadTask didResumeAtOffset:fileOffset expectedTotalBytes:expectedTotalBytes];
|
||||
|
||||
if (self.downloadTaskDidResume) {
|
||||
self.downloadTaskDidResume(session, downloadTask, fileOffset, expectedTotalBytes);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - NSKeyValueObserving
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
if (context == AFTaskStateChangedContext && [keyPath isEqualToString:@"state"]) {
|
||||
NSString *notificationName = nil;
|
||||
switch ([(NSURLSessionTask *)object state]) {
|
||||
case NSURLSessionTaskStateRunning:
|
||||
notificationName = AFNetworkingTaskDidResumeNotification;
|
||||
break;
|
||||
case NSURLSessionTaskStateSuspended:
|
||||
notificationName = AFNetworkingTaskDidSuspendNotification;
|
||||
break;
|
||||
case NSURLSessionTaskStateCompleted:
|
||||
// AFNetworkingTaskDidFinishNotification posted by task completion handlers
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (notificationName) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:object];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
NSURLSessionConfiguration *configuration = [decoder decodeObjectForKey:@"sessionConfiguration"];
|
||||
NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"];
|
||||
|
||||
self = [self initWithSessionConfiguration:configuration];
|
||||
if (!self) {
|
||||
|
||||
4
www/cordovaHTTP.js
vendored
4
www/cordovaHTTP.js
vendored
@@ -63,6 +63,8 @@ var http = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = http;
|
||||
|
||||
if (typeof angular !== "undefined") {
|
||||
angular.module('cordovaHTTP', []).factory('cordovaHTTP', function($timeout, $q) {
|
||||
function makePromise(fn, args, async) {
|
||||
@@ -126,4 +128,4 @@ if (typeof angular !== "undefined") {
|
||||
});
|
||||
} else {
|
||||
window.cordovaHTTP = http;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user