Commit 88ce850a by 徐利超

update

parent 509c1dfa
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
#import "YUNXINDemoViewController.h" #import "YUNXINDemoViewController.h"
#import <CommonCrypto/CommonCryptor.h> #import <CommonCrypto/CommonCryptor.h>
#import "CHNetworkingManager.h" #import "CHNetworkingManager.h"
#import <AFJSONRPCClient/AFJSONRPCClient.h>
#import <AFNetworking/AFHTTPRequestOperationManager.h>
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@interface LoginViewController () @interface LoginViewController ()
...@@ -196,8 +198,8 @@ static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopq ...@@ -196,8 +198,8 @@ static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopq
// vc.otherUid = self.otherUid; // vc.otherUid = self.otherUid;
// vc.modalPresentationStyle = UIModalPresentationFullScreen; // vc.modalPresentationStyle = UIModalPresentationFullScreen;
// [self presentViewController:vc animated:YES completion:nil]; // [self presentViewController:vc animated:YES completion:nil];
// [self sendASRNLPReq]; [self sendASRNLPReq];
[self TTSSessionBegin]; // [self TTSSessionBegin];
} }
...@@ -219,9 +221,9 @@ static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopq ...@@ -219,9 +221,9 @@ static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopq
@"account":@"50006" @"account":@"50006"
}; };
[[CHNetworkingManager new] httpRequsetForUploadFile:data param:dic onSuccessBlock:^(NSDictionary *dic) { [[CHNetworkingManager new] httpRequsetForUploadFile:data param:dic onSuccessBlock:^(NSDictionary *dic) {
NSLog(@"===>>> asr,nlp success:%@",dic);
} failureBlock:^(NSError *error) { } failureBlock:^(NSError *error) {
NSLog(@"===>>> asr,nlp error:%@",error.domain);
}]; }];
} }
...@@ -251,11 +253,21 @@ static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopq ...@@ -251,11 +253,21 @@ static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopq
}; };
NSDictionary *sendDic = [self getSendJsonWithCmd:1 param:param]; NSDictionary *sendDic = [self getSendJsonWithCmd:1 param:param];
[[CHNetworkingManager new] requestJsonStringPOSTWithParameter:[self dictionaryToJSONString:sendDic] successBlock:^(NSDictionary *dic) { AFJSONRPCClient *client = [AFJSONRPCClient clientWithEndpointURL:[NSURL URLWithString:@"http://fhts.test.bank.ecitic.com/voicePre/portal/tts"]];
NSLog(@"===>>> tts:ssb success:%@",dic); if (client) {
} failureBlock:^(NSError *error) { [client invokeMethod:@"" withParameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"===>>> tts:ssb error:%@", error.domain); NSLog(@"===>>> tts:ssb success:%@",responseObject);
}]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"===>>> tts:ssb error:%@",error.userInfo);
}];
}else {
NSLog(@"client uninit");
}
// [[CHNetworkingManager new] requestJsonStringPOSTWithParameter:[self dictionaryToJSONString:sendDic] successBlock:^(NSDictionary *dic) {
// NSLog(@"===>>> tts:ssb success:%@",dic);
// } failureBlock:^(NSError *error) {
// NSLog(@"===>>> tts:ssb error:%@", error.domain);
// }];
} }
......
...@@ -69,7 +69,7 @@ typedef enum : NSUInteger { ...@@ -69,7 +69,7 @@ typedef enum : NSUInteger {
switch (method) { switch (method) {
case GET:{ case GET:{
[self GET:url parameters:param progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { [self GET:url parameters:param success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(responseObject); success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if(self.count == 0) { if(self.count == 0) {
...@@ -85,7 +85,7 @@ typedef enum : NSUInteger { ...@@ -85,7 +85,7 @@ typedef enum : NSUInteger {
break; break;
} }
case POST:{ case POST:{
[self POST:url parameters:param progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { [self POST:url parameters:param success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(responseObject); success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if(self.count == 0) { if(self.count == 0) {
...@@ -170,13 +170,16 @@ typedef enum : NSUInteger { ...@@ -170,13 +170,16 @@ typedef enum : NSUInteger {
[request setHTTPBody:[jsonStr dataUsingEncoding:NSUTF8StringEncoding]]; [request setHTTPBody:[jsonStr dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:config]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:config];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { NSURLSessionTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) { if (error) {
failure(error); failure(error);
}else { }else {
success(responseObject); success(responseObject);
} }
}]; }];
// NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
//
// }];
[dataTask resume]; [dataTask resume];
} }
...@@ -195,7 +198,6 @@ typedef enum : NSUInteger { ...@@ -195,7 +198,6 @@ typedef enum : NSUInteger {
// [self.requestSerializer setValue:@"iOS" forHTTPHeaderField:@"device"]; // [self.requestSerializer setValue:@"iOS" forHTTPHeaderField:@"device"];
// [self.requestSerializer setValue:[CHVersionTool getBundleShortVersionString] forHTTPHeaderField:@"version"]; // [self.requestSerializer setValue:[CHVersionTool getBundleShortVersionString] forHTTPHeaderField:@"version"];
[self POST:url parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { [self POST:url parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
if (data) { if (data) {
// 在网络开发中,上传文件时,是文件不允许被覆盖,文件重名 // 在网络开发中,上传文件时,是文件不允许被覆盖,文件重名
// 要解决此问题, // 要解决此问题,
...@@ -208,14 +210,34 @@ typedef enum : NSUInteger { ...@@ -208,14 +210,34 @@ typedef enum : NSUInteger {
[formData appendPartWithFileData:data name:dataName fileName:fileName mimeType:@"pcm"]; [formData appendPartWithFileData:data name:dataName fileName:fileName mimeType:@"pcm"];
} }
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
success(responseObject); success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(error); failure(error);
}]; }];
// [self POST:url parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
//
// if (data) {
// // 在网络开发中,上传文件时,是文件不允许被覆盖,文件重名
// // 要解决此问题,
// // 可以在上传时使用当前的系统时间作为文件名
// NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// // 设置时间格式
// formatter.dateFormat = @"yyyyMMddHHmmss";
// NSString *str = [formatter stringFromDate:[NSDate date]];
// NSString *fileName = [NSString stringWithFormat:@"%@.pcm", str];
//
// [formData appendPartWithFileData:data name:dataName fileName:fileName mimeType:@"pcm"];
// }
//
// } progress:^(NSProgress * _Nonnull uploadProgress) {
//
// } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// success(responseObject);
// } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
// failure(error);
// }];
} }
- (CHNetWorkStatus)isNetWorkEnable { - (CHNetWorkStatus)isNetWorkEnable {
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
failureBlock:(RequestFailureInfoBlock)failure failureBlock:(RequestFailureInfoBlock)failure
{ {
TraceS(@"=====>>>> func:%@",func); TraceS(@"=====>>>> func:%@",func);
NSString *mainUrl = @"http://192.168.60.72:8080"; NSString *mainUrl = @"http://192.168.43.142:8080";
[[CHNetworkingRequest sharedClient] requestformDataWithPath:mainUrl functionName:func param:param data:data dataName:dataName successBlock:^(NSDictionary *dic) { [[CHNetworkingRequest sharedClient] requestformDataWithPath:mainUrl functionName:func param:param data:data dataName:dataName successBlock:^(NSDictionary *dic) {
success(dic); success(dic);
} failureBlock:^(NSDictionary *dic, NSError *error) { } failureBlock:^(NSDictionary *dic, NSError *error) {
......
PODS: PODS:
- AFNetworking (3.2.1): - AFJSONRPCClient (2.1.1):
- AFNetworking/NSURLSession (= 3.2.1) - AFNetworking (~> 2.1)
- AFNetworking/Reachability (= 3.2.1) - AFNetworking (2.7.0):
- AFNetworking/Security (= 3.2.1) - AFNetworking/NSURLConnection (= 2.7.0)
- AFNetworking/Serialization (= 3.2.1) - AFNetworking/NSURLSession (= 2.7.0)
- AFNetworking/UIKit (= 3.2.1) - AFNetworking/Reachability (= 2.7.0)
- AFNetworking/NSURLSession (3.2.1): - AFNetworking/Security (= 2.7.0)
- AFNetworking/Serialization (= 2.7.0)
- AFNetworking/UIKit (= 2.7.0)
- AFNetworking/NSURLConnection (2.7.0):
- AFNetworking/Reachability - AFNetworking/Reachability
- AFNetworking/Security - AFNetworking/Security
- AFNetworking/Serialization - AFNetworking/Serialization
- AFNetworking/Reachability (3.2.1) - AFNetworking/NSURLSession (2.7.0):
- AFNetworking/Security (3.2.1) - AFNetworking/Reachability
- AFNetworking/Serialization (3.2.1) - AFNetworking/Security
- AFNetworking/UIKit (3.2.1): - AFNetworking/Serialization
- AFNetworking/Reachability (2.7.0)
- AFNetworking/Security (2.7.0)
- AFNetworking/Serialization (2.7.0)
- AFNetworking/UIKit (2.7.0):
- AFNetworking/NSURLConnection
- AFNetworking/NSURLSession - AFNetworking/NSURLSession
- IQKeyboardManager (6.5.6) - IQKeyboardManager (6.5.6)
- Masonry (1.1.0) - Masonry (1.1.0)
DEPENDENCIES: DEPENDENCIES:
- AFJSONRPCClient
- AFNetworking - AFNetworking
- IQKeyboardManager - IQKeyboardManager
- Masonry - Masonry
SPEC REPOS: SPEC REPOS:
https://github.com/CocoaPods/Specs.git: https://github.com/CocoaPods/Specs.git:
- AFJSONRPCClient
- AFNetworking - AFNetworking
- IQKeyboardManager - IQKeyboardManager
- Masonry - Masonry
SPEC CHECKSUMS: SPEC CHECKSUMS:
AFNetworking: b6f891fdfaed196b46c7a83cf209e09697b94057 AFJSONRPCClient: 333bada91e6e45398446b8bd84e238e6f2389b1b
AFNetworking: 8dd5f9b9691e09186393069a12cc3b5ed7c8b511
IQKeyboardManager: 2a6e97afdafc7becf0cb17a9a8d795e3a980717f IQKeyboardManager: 2a6e97afdafc7becf0cb17a9a8d795e3a980717f
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
PODFILE CHECKSUM: 05dc85bcfeedc8253c411e67a7ee98c5ff6bdd07 PODFILE CHECKSUM: c17dd2b51db38ebc1361046f88ac3934293eb4ef
COCOAPODS: 1.8.3 COCOAPODS: 1.8.3
// AFJSONRPCClient.m
//
// Created by wiistriker@gmail.com
// Copyright (c) 2013 JustCommunication
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <AFNetworking/AFHTTPRequestOperationManager.h>
/**
AFJSONRPCClient objects communicate with web services using the JSON-RPC 2.0 protocol.
@see http://www.jsonrpc.org/specification
*/
@interface AFJSONRPCClient : AFHTTPRequestOperationManager
/**
The endpoint URL for the webservice.
*/
@property (readonly, nonatomic, strong) NSURL *endpointURL;
/**
Creates and initializes a JSON-RPC client with the specified endpoint.
@param URL The endpoint URL.
@return An initialized JSON-RPC client.
*/
+ (instancetype)clientWithEndpointURL:(NSURL *)URL;
/**
Initializes a JSON-RPC client with the specified endpoint.
@param URL The endpoint URL.
@return An initialized JSON-RPC client.
*/
- (id)initWithEndpointURL:(NSURL *)URL;
/**
Creates a request with the specified HTTP method, parameters, and request ID.
@param method The HTTP method. Must not be `nil`.
@param parameters The parameters to encode into the request. Must be either an `NSDictionary` or `NSArray`.
@param requestId The ID of the request.
@return A JSON-RPC-encoded request.
*/
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
parameters:(id)parameters
requestId:(id)requestId;
/**
Creates a request with the specified method, and enqueues a request operation for it.
@param method The HTTP method. Must not be `nil`.
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
*/
- (void)invokeMethod:(NSString *)method
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
/**
Creates a request with the specified method and parameters, and enqueues a request operation for it.
@param method The HTTP method. Must not be `nil`.
@param parameters The parameters to encode into the request. Must be either an `NSDictionary` or `NSArray`.
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
*/
- (void)invokeMethod:(NSString *)method
withParameters:(id)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
/**
Creates a request with the specified method and parameters, and enqueues a request operation for it.
@param method The HTTP method. Must not be `nil`.
@param parameters The parameters to encode into the request. Must be either an `NSDictionary` or `NSArray`.
@param requestId The ID of the request.
@param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer.
@param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred.
*/
- (void)invokeMethod:(NSString *)method
withParameters:(id)parameters
requestId:(id)requestId
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
///----------------------
/// @name Method Proxying
///----------------------
/**
Returns a JSON-RPC client proxy object with methods conforming to the specified protocol.
@param protocol The protocol.
@discussion This approach allows Objective-C messages to be transparently forwarded as JSON-RPC calls.
*/
- (id)proxyWithProtocol:(Protocol *)protocol;
@end
///----------------
/// @name Constants
///----------------
/**
AFJSONRPCClient errors.
*/
extern NSString * const AFJSONRPCErrorDomain;
// AFJSONRPCClient.m
//
// Created by wiistriker@gmail.com
// Copyright (c) 2013 JustCommunication
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "AFJSONRPCClient.h"
#import "AFHTTPRequestOperation.h"
#import <objc/runtime.h>
NSString * const AFJSONRPCErrorDomain = @"com.alamofire.networking.json-rpc";
static NSString * AFJSONRPCLocalizedErrorMessageForCode(NSInteger code) {
switch(code) {
case -32700:
return @"Parse Error";
case -32600:
return @"Invalid Request";
case -32601:
return @"Method Not Found";
case -32602:
return @"Invalid Params";
case -32603:
return @"Internal Error";
default:
return @"Server Error";
}
}
@interface AFJSONRPCProxy : NSProxy
- (id)initWithClient:(AFJSONRPCClient *)client
protocol:(Protocol *)protocol;
@end
#pragma mark -
@interface AFJSONRPCClient ()
@property (readwrite, nonatomic, strong) NSURL *endpointURL;
@end
@implementation AFJSONRPCClient
+ (instancetype)clientWithEndpointURL:(NSURL *)URL {
return [[self alloc] initWithEndpointURL:URL];
}
- (id)initWithEndpointURL:(NSURL *)URL {
NSParameterAssert(URL);
self = [super initWithBaseURL:URL];
if (!self) {
return nil;
}
self.requestSerializer = [AFJSONRequestSerializer serializer];
[self.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
self.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"application/json-rpc", @"application/jsonrequest", nil];
self.endpointURL = URL;
return self;
}
- (void)invokeMethod:(NSString *)method
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
[self invokeMethod:method withParameters:@[] success:success failure:failure];
}
- (void)invokeMethod:(NSString *)method
withParameters:(id)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
[self invokeMethod:method withParameters:parameters requestId:@(1) success:success failure:failure];
}
- (void)invokeMethod:(NSString *)method
withParameters:(id)parameters
requestId:(id)requestId
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
NSMutableURLRequest *request = [self requestWithMethod:method parameters:parameters requestId:requestId];
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
[self.operationQueue addOperation:operation];
}
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
parameters:(id)parameters
requestId:(id)requestId
{
NSParameterAssert(method);
if (!parameters) {
parameters = @[];
}
NSAssert([parameters isKindOfClass:[NSDictionary class]] || [parameters isKindOfClass:[NSArray class]], @"Expect NSArray or NSDictionary in JSONRPC parameters");
if (!requestId) {
requestId = @(1);
}
NSMutableDictionary *payload = [NSMutableDictionary dictionary];
payload[@"jsonrpc"] = @"2.0";
payload[@"method"] = method;
payload[@"params"] = parameters;
payload[@"id"] = [requestId description];
return [self.requestSerializer requestWithMethod:@"POST" URLString:[self.endpointURL absoluteString] parameters:payload error:nil];
}
#pragma mark - AFHTTPClient
- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
return [super HTTPRequestOperationWithRequest:urlRequest success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSInteger code = 0;
NSString *message = nil;
id data = nil;
if ([responseObject isKindOfClass:[NSDictionary class]]) {
id result = responseObject[@"result"];
id error = responseObject[@"error"];
if (result && result != [NSNull null]) {
if (success) {
success(operation, result);
return;
}
} else if (error && error != [NSNull null]) {
if ([error isKindOfClass:[NSDictionary class]]) {
if (error[@"code"]) {
code = [error[@"code"] integerValue];
}
if (error[@"message"]) {
message = error[@"message"];
} else if (code) {
message = AFJSONRPCLocalizedErrorMessageForCode(code);
}
data = error[@"data"];
} else {
message = NSLocalizedStringFromTable(@"Unknown Error", @"AFJSONRPCClient", nil);
}
} else {
message = NSLocalizedStringFromTable(@"Unknown JSON-RPC Response", @"AFJSONRPCClient", nil);
}
} else {
message = NSLocalizedStringFromTable(@"Unknown JSON-RPC Response", @"AFJSONRPCClient", nil);
}
if (failure) {
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
if (message) {
userInfo[NSLocalizedDescriptionKey] = message;
}
if (data) {
userInfo[@"data"] = data;
}
NSError *error = [NSError errorWithDomain:AFJSONRPCErrorDomain code:code userInfo:userInfo];
failure(operation, error);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (failure) {
failure(operation, error);
}
}];
}
- (id)proxyWithProtocol:(Protocol *)protocol {
return [[AFJSONRPCProxy alloc] initWithClient:self protocol:protocol];
}
@end
#pragma mark -
typedef void (^AFJSONRPCProxySuccessBlock)(id responseObject);
typedef void (^AFJSONRPCProxyFailureBlock)(NSError *error);
@interface AFJSONRPCProxy ()
@property (readwrite, nonatomic, strong) AFJSONRPCClient *client;
@property (readwrite, nonatomic, strong) Protocol *protocol;
@end
@implementation AFJSONRPCProxy
- (id)initWithClient:(AFJSONRPCClient*)client
protocol:(Protocol *)protocol
{
self.client = client;
self.protocol = protocol;
return self;
}
- (BOOL)respondsToSelector:(SEL)selector {
struct objc_method_description description = protocol_getMethodDescription(self.protocol, selector, YES, YES);
return description.name != NULL;
}
- (NSMethodSignature *)methodSignatureForSelector:(__unused SEL)selector {
// 0: v->RET || 1: @->self || 2: :->SEL || 3: @->arg#0 (NSArray) || 4,5: ^v->arg#1,2 (block)
NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:"v@:@^v^v"];
return signature;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
NSParameterAssert(invocation.methodSignature.numberOfArguments == 5);
NSString *RPCMethod = [NSStringFromSelector([invocation selector]) componentsSeparatedByString:@":"][0];
__unsafe_unretained id arguments;
__unsafe_unretained AFJSONRPCProxySuccessBlock unsafeSuccess;
__unsafe_unretained AFJSONRPCProxyFailureBlock unsafeFailure;
[invocation getArgument:&arguments atIndex:2];
[invocation getArgument:&unsafeSuccess atIndex:3];
[invocation getArgument:&unsafeFailure atIndex:4];
[invocation invokeWithTarget:nil];
__strong AFJSONRPCProxySuccessBlock strongSuccess = [unsafeSuccess copy];
__strong AFJSONRPCProxyFailureBlock strongFailure = [unsafeFailure copy];
[self.client invokeMethod:RPCMethod withParameters:arguments success:^(__unused AFHTTPRequestOperation *operation, id responseObject) {
if (strongSuccess) {
strongSuccess(responseObject);
}
} failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) {
if (strongFailure) {
strongFailure(error);
}
}];
}
@end
Copyright (c) 2013 JustCommunication
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# AFJSONRPCClient
**A [JSON-RPC](http://json-rpc.org/) Client built on [AFNetworking](https://github.com/AFNetworking/AFNetworking)**
> [JSON-RPC](http://json-rpc.org/) is a [remote procedure call](http://en.wikipedia.org/wiki/Remote_procedure_call) protocol encoded in [JSON](http://en.wikipedia.org/wiki/JSON). It is a simple protocol (and very similar to [XML-RPC](http://en.wikipedia.org/wiki/XML-RPC)), defining only a handful of data types and commands. JSON-RPC allows for notifications (info sent to the server that does not require a response) and for multiple calls to be sent to the server which may be answered out of order.
## Example Usage
``` objective-c
AFJSONRPCClient *client = [AFJSONRPCClient clientWithEndpointURL:[NSURL URLWithString:@"http://path.to/json-rpc/service/"]];
// Invocation
[client invokeMethod:@"method.name"
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
// ...
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// ...
}];
// Invocation with Parameters
[client invokeMethod:@"method.name"
parameters:@{@"foo" : @"bar", @"baz" : @(13)}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// ...
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// ...
}];
// Invocation with Parameters and Request ID
[client invokeMethod:@"method.name"
parameters:@[@(YES), @(42)]
requestId:@(2)
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// ...
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// ...
}];
```
## Using Protocol & NSProxy
Combine your JSON-RPC client with an Objective-C protocol for fun and profit!
``` objective-c
@protocol ArithemeticProtocol
- (void)sum:(NSArray *)numbers
success:(void (^)(NSNumber *sum))success;
failure:(void (^)(NSError *error))failure;
@end
AFJSONRPCClient *client = [AFJSONRPCClient clientWithEndpointURL:[NSURL URLWithString:@"http://path.to/json-rpc/service/"]];
[[client proxyForProtocol:@protocol(ArithemeticProtocol)] sum:@[@(1), @(2)]
success:^(NSNumber *sum) {
// ...
} failure:^(NSError *error) {
// ...
}];
```
## Subclassing
You can also subclass `AFJSONRPCClient` for shared class and service-related methods:
``` objective-c
MyJSONRPCClient *client = [MyJSONRPCClient sharedClient];
[client sum:@[@(1), @(2)]
success:^(NSNumber *sum) {
// ...
} failure:^(NSError *error) {
// ...
}];
```
## Installation
[CocoaPods](http://cocoapods.org) is the recommended way to add AFJSONRPCClient to your project.
Here's an example podfile that installs AFJSONRPCClient and its dependency, AFNetworking.
### Podfile
```ruby
platform :ios, '5.0'
pod 'AFJSONRPCClient', '0.1.0'
```
Note the specification of iOS 5.0 as the platform; leaving out the 5.0 will cause CocoaPods to fail with the following message:
> [!] AFJSONRPCClient is not compatible with iOS 4.3.
## License
AFJSONRPCClient and AFNetworking are available under the MIT license. See the LICENSE file for more info.
// AFCompatibilityMacros.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef AFCompatibilityMacros_h
#define AFCompatibilityMacros_h
#ifdef API_UNAVAILABLE
#define AF_API_UNAVAILABLE(x) API_UNAVAILABLE(x)
#else
#define AF_API_UNAVAILABLE(x)
#endif // API_UNAVAILABLE
#if __has_warning("-Wunguarded-availability-new")
#define AF_CAN_USE_AT_AVAILABLE 1
#else
#define AF_CAN_USE_AT_AVAILABLE 0
#endif
#endif /* AFCompatibilityMacros_h */
// AFHTTPRequestOperation.h
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import "AFURLConnectionOperation.h"
NS_ASSUME_NONNULL_BEGIN
/**
`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.
*/
@interface AFHTTPRequestOperation : AFURLConnectionOperation
///------------------------------------------------
/// @name Getting HTTP URL Connection Information
///------------------------------------------------
/**
The last HTTP response received by the operation's connection.
*/
@property (readonly, nonatomic, strong, nullable) NSHTTPURLResponse *response;
/**
Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an AFHTTPResponse serializer, which uses the raw data as its response object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed.
@warning `responseSerializer` must not be `nil`. Setting a response serializer will clear out any cached value
*/
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;
/**
An object constructed by the `responseSerializer` from the response and response data. Returns `nil` unless the operation `isFinished`, has a `response`, and has `responseData` with non-zero content length. If an error occurs during serialization, `nil` will be returned, and the `error` property will be populated with the serialization error.
*/
@property (readonly, nonatomic, strong, nullable) id responseObject;
///-----------------------------------------------------------
/// @name Setting Completion Block Success / Failure Callbacks
///-----------------------------------------------------------
/**
Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed.
This method should be overridden in subclasses in order to specify the response object passed into the success block.
@param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request.
@param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request.
*/
- (void)setCompletionBlockWithSuccess:(nullable void (^)(AFHTTPRequestOperation *operation, id __nullable responseObject))success
failure:(nullable void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
@end
NS_ASSUME_NONNULL_END
// AFHTTPRequestOperation.m
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "AFHTTPRequestOperation.h"
static dispatch_queue_t http_request_operation_processing_queue() {
static dispatch_queue_t af_http_request_operation_processing_queue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
af_http_request_operation_processing_queue = dispatch_queue_create("com.alamofire.networking.http-request.processing", DISPATCH_QUEUE_CONCURRENT);
});
return af_http_request_operation_processing_queue;
}
static dispatch_group_t http_request_operation_completion_group() {
static dispatch_group_t af_http_request_operation_completion_group;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
af_http_request_operation_completion_group = dispatch_group_create();
});
return af_http_request_operation_completion_group;
}
#pragma mark -
@interface AFURLConnectionOperation ()
@property (readwrite, nonatomic, strong) NSURLRequest *request;
@property (readwrite, nonatomic, strong) NSURLResponse *response;
@end
@interface AFHTTPRequestOperation ()
@property (readwrite, nonatomic, strong) NSHTTPURLResponse *response;
@property (readwrite, nonatomic, strong, nullable) id responseObject;
@property (readwrite, nonatomic, strong) NSError *responseSerializationError;
@property (readwrite, nonatomic, strong) NSRecursiveLock *lock;
@end
@implementation AFHTTPRequestOperation
@dynamic response;
@dynamic lock;
- (instancetype)initWithRequest:(NSURLRequest *)urlRequest {
self = [super initWithRequest:urlRequest];
if (!self) {
return nil;
}
self.responseSerializer = [AFHTTPResponseSerializer serializer];
return self;
}
- (void)setResponseSerializer:(AFHTTPResponseSerializer <AFURLResponseSerialization> *)responseSerializer {
NSParameterAssert(responseSerializer);
[self.lock lock];
_responseSerializer = responseSerializer;
self.responseObject = nil;
self.responseSerializationError = nil;
[self.lock unlock];
}
- (id)responseObject {
[self.lock lock];
if (!_responseObject && [self isFinished] && !self.error) {
NSError *error = nil;
self.responseObject = [self.responseSerializer responseObjectForResponse:self.response data:self.responseData error:&error];
if (error) {
self.responseSerializationError = error;
}
}
[self.lock unlock];
return _responseObject;
}
- (NSError *)error {
if (_responseSerializationError) {
return _responseSerializationError;
} else {
return [super error];
}
}
#pragma mark - AFHTTPRequestOperation
- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id __nullable responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
// completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-retain-cycles"
#pragma clang diagnostic ignored "-Wgnu"
self.completionBlock = ^{
if (self.completionGroup) {
dispatch_group_enter(self.completionGroup);
}
dispatch_async(http_request_operation_processing_queue(), ^{
if (self.error) {
if (failure) {
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(self, self.error);
});
}
} else {
id responseObject = self.responseObject;
if (self.error) {
if (failure) {
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(self, self.error);
});
}
} else {
if (success) {
dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{
success(self, responseObject);
});
}
}
}
if (self.completionGroup) {
dispatch_group_leave(self.completionGroup);
}
});
};
#pragma clang diagnostic pop
}
#pragma mark - AFURLRequestOperation
- (void)pause {
[super pause];
u_int64_t offset = 0;
if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) {
offset = [(NSNumber *)[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedLongLongValue];
} else {
offset = [(NSData *)[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length];
}
NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy];
if ([self.response respondsToSelector:@selector(allHeaderFields)] && [[self.response allHeaderFields] valueForKey:@"ETag"]) {
[mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:@"ETag"] forHTTPHeaderField:@"If-Range"];
}
[mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"];
self.request = mutableURLRequest;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (!self) {
return nil;
}
self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[super encodeWithCoder:coder];
[coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))];
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone {
AFHTTPRequestOperation *operation = [super copyWithZone:zone];
operation.responseSerializer = [self.responseSerializer copyWithZone:zone];
operation.completionQueue = self.completionQueue;
operation.completionGroup = self.completionGroup;
return operation;
}
@end
// AFNetworkReachabilityManager.h // AFNetworkReachabilityManager.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -24,6 +24,14 @@ ...@@ -24,6 +24,14 @@
#if !TARGET_OS_WATCH #if !TARGET_OS_WATCH
#import <SystemConfiguration/SystemConfiguration.h> #import <SystemConfiguration/SystemConfiguration.h>
#ifndef NS_DESIGNATED_INITIALIZER
#if __has_attribute(objc_designated_initializer)
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
#else
#define NS_DESIGNATED_INITIALIZER
#endif
#endif
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1, AFNetworkReachabilityStatusUnknown = -1,
AFNetworkReachabilityStatusNotReachable = 0, AFNetworkReachabilityStatusNotReachable = 0,
...@@ -38,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -38,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN
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. 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/ ) 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. @warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined.
*/ */
...@@ -74,13 +82,6 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -74,13 +82,6 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)sharedManager; + (instancetype)sharedManager;
/** /**
Creates and returns a network reachability manager with the default socket address.
@return An initialized network reachability manager, actively monitoring the default socket address.
*/
+ (instancetype)manager;
/**
Creates and returns a network reachability manager for the specified domain. Creates and returns a network reachability manager for the specified domain.
@param domain The domain used to evaluate network reachability. @param domain The domain used to evaluate network reachability.
...@@ -92,7 +93,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -92,7 +93,7 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
Creates and returns a network reachability manager for the socket address. Creates and returns a network reachability manager for the socket address.
@param address The socket address (`sockaddr_in6`) 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. @return An initialized network reachability manager, actively monitoring the specified socket address.
*/ */
......
// AFNetworkReachabilityManager.m // AFNetworkReachabilityManager.m
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -94,7 +94,6 @@ static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused targ ...@@ -94,7 +94,6 @@ static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused targ
AFPostReachabilityStatusChange(flags, (__bridge AFNetworkReachabilityStatusBlock)info); AFPostReachabilityStatusChange(flags, (__bridge AFNetworkReachabilityStatusBlock)info);
} }
static const void * AFNetworkReachabilityRetainCallback(const void *info) { static const void * AFNetworkReachabilityRetainCallback(const void *info) {
return Block_copy(info); return Block_copy(info);
} }
...@@ -117,7 +116,12 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { ...@@ -117,7 +116,12 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
static AFNetworkReachabilityManager *_sharedManager = nil; static AFNetworkReachabilityManager *_sharedManager = nil;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
_sharedManager = [self manager]; struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_len = sizeof(address);
address.sin_family = AF_INET;
_sharedManager = [self managerForAddress:&address];
}); });
return _sharedManager; return _sharedManager;
...@@ -142,22 +146,6 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { ...@@ -142,22 +146,6 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
return manager; return manager;
} }
+ (instancetype)manager
{
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
struct sockaddr_in6 address;
bzero(&address, sizeof(address));
address.sin6_len = sizeof(address);
address.sin6_family = AF_INET6;
#else
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_len = sizeof(address);
address.sin_family = AF_INET;
#endif
return [self managerForAddress:&address];
}
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability { - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
self = [super init]; self = [super init];
if (!self) { if (!self) {
...@@ -170,7 +158,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) { ...@@ -170,7 +158,7 @@ static void AFNetworkReachabilityReleaseCallback(const void *info) {
return self; return self;
} }
- (instancetype)init - (instancetype)init NS_UNAVAILABLE
{ {
@throw [NSException exceptionWithName:NSGenericException @throw [NSException exceptionWithName:NSGenericException
reason:@"`-init` unavailable. Use `-initWithReachability:` instead" reason:@"`-init` unavailable. Use `-initWithReachability:` instead"
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <Availability.h> #import <Availability.h>
#import <TargetConditionals.h>
#ifndef _AFNETWORKING_ #ifndef _AFNETWORKING_
#define _AFNETWORKING_ #define _AFNETWORKING_
...@@ -30,12 +29,18 @@ ...@@ -30,12 +29,18 @@
#import "AFURLRequestSerialization.h" #import "AFURLRequestSerialization.h"
#import "AFURLResponseSerialization.h" #import "AFURLResponseSerialization.h"
#import "AFSecurityPolicy.h" #import "AFSecurityPolicy.h"
#if !TARGET_OS_WATCH #if !TARGET_OS_WATCH
#import "AFNetworkReachabilityManager.h" #import "AFNetworkReachabilityManager.h"
#import "AFURLConnectionOperation.h"
#import "AFHTTPRequestOperation.h"
#import "AFHTTPRequestOperationManager.h"
#endif #endif
#if ( ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || \
( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 ) || \
TARGET_OS_WATCH )
#import "AFURLSessionManager.h" #import "AFURLSessionManager.h"
#import "AFHTTPSessionManager.h" #import "AFHTTPSessionManager.h"
#endif
#endif /* _AFNETWORKING_ */ #endif /* _AFNETWORKING_ */
// AFSecurityPolicy.h // AFSecurityPolicy.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -44,13 +44,9 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -44,13 +44,9 @@ NS_ASSUME_NONNULL_BEGIN
@property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode; @property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
/** /**
The certificates used to evaluate server trust according to the SSL pinning mode. The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the app bundle. Note that if you create an array with duplicate certificates, the duplicate certificates will be removed. Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches.
By default, this property is set to any (`.cer`) certificates included in the target compiling AFNetworking. Note that if you are using AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`.
Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches.
*/ */
@property (nonatomic, strong, nullable) NSSet <NSData *> *pinnedCertificates; @property (nonatomic, strong, nullable) NSArray *pinnedCertificates;
/** /**
Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`. Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
...@@ -63,17 +59,6 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -63,17 +59,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) BOOL validatesDomainName; @property (nonatomic, assign) BOOL validatesDomainName;
///----------------------------------------- ///-----------------------------------------
/// @name Getting Certificates from the Bundle
///-----------------------------------------
/**
Returns any certificates included in the bundle. If you are using AFNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`.
@return The certificates included in the given bundle.
*/
+ (NSSet <NSData *> *)certificatesInBundle:(NSBundle *)bundle;
///-----------------------------------------
/// @name Getting Specific Security Policies /// @name Getting Specific Security Policies
///----------------------------------------- ///-----------------------------------------
...@@ -97,19 +82,22 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -97,19 +82,22 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode; + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode;
///------------------------------
/// @name Evaluating Server Trust
///------------------------------
/** /**
Creates and returns a security policy with the specified pinning mode. Whether or not the specified server trust should be accepted, based on the security policy.
@param pinningMode The SSL pinning mode. This method should be used when responding to an authentication challenge from a server.
@param pinnedCertificates The certificates to pin against.
@return A new security policy. @param serverTrust The X.509 certificate trust of the server.
*/
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet <NSData *> *)pinnedCertificates;
///------------------------------ @return Whether or not to trust the server.
/// @name Evaluating Server Trust
///------------------------------ @warning This method has been deprecated in favor of `-evaluateServerTrust:forDomain:`.
*/
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust DEPRECATED_ATTRIBUTE;
/** /**
Whether or not the specified server trust should be accepted, based on the security policy. Whether or not the specified server trust should be accepted, based on the security policy.
......
// AFSecurityPolicy.m // AFSecurityPolicy.m
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#import <AssertMacros.h> #import <AssertMacros.h>
#if !TARGET_OS_IOS && !TARGET_OS_WATCH && !TARGET_OS_TV #if !TARGET_OS_IOS && !TARGET_OS_WATCH
static NSData * AFSecKeyGetData(SecKeyRef key) { static NSData * AFSecKeyGetData(SecKeyRef key) {
CFDataRef data = NULL; CFDataRef data = NULL;
...@@ -41,7 +41,7 @@ _out: ...@@ -41,7 +41,7 @@ _out:
#endif #endif
static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) { static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) {
#if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV #if TARGET_OS_IOS || TARGET_OS_WATCH
return [(__bridge id)key1 isEqual:(__bridge id)key2]; return [(__bridge id)key1 isEqual:(__bridge id)key2];
#else #else
return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)]; return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)];
...@@ -51,6 +51,8 @@ static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) { ...@@ -51,6 +51,8 @@ static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) {
static id AFPublicKeyForCertificate(NSData *certificate) { static id AFPublicKeyForCertificate(NSData *certificate) {
id allowedPublicKey = nil; id allowedPublicKey = nil;
SecCertificateRef allowedCertificate; SecCertificateRef allowedCertificate;
SecCertificateRef allowedCertificates[1];
CFArrayRef tempCertificates = nil;
SecPolicyRef policy = nil; SecPolicyRef policy = nil;
SecTrustRef allowedTrust = nil; SecTrustRef allowedTrust = nil;
SecTrustResultType result; SecTrustResultType result;
...@@ -58,8 +60,11 @@ static id AFPublicKeyForCertificate(NSData *certificate) { ...@@ -58,8 +60,11 @@ static id AFPublicKeyForCertificate(NSData *certificate) {
allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate); allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate);
__Require_Quiet(allowedCertificate != NULL, _out); __Require_Quiet(allowedCertificate != NULL, _out);
allowedCertificates[0] = allowedCertificate;
tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL);
policy = SecPolicyCreateBasicX509(); policy = SecPolicyCreateBasicX509();
__Require_noErr_Quiet(SecTrustCreateWithCertificates(allowedCertificate, policy, &allowedTrust), _out); __Require_noErr_Quiet(SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust), _out);
__Require_noErr_Quiet(SecTrustEvaluate(allowedTrust, &result), _out); __Require_noErr_Quiet(SecTrustEvaluate(allowedTrust, &result), _out);
allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust); allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust);
...@@ -73,6 +78,10 @@ _out: ...@@ -73,6 +78,10 @@ _out:
CFRelease(policy); CFRelease(policy);
} }
if (tempCertificates) {
CFRelease(tempCertificates);
}
if (allowedCertificate) { if (allowedCertificate) {
CFRelease(allowedCertificate); CFRelease(allowedCertificate);
} }
...@@ -141,29 +150,25 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { ...@@ -141,29 +150,25 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
@interface AFSecurityPolicy() @interface AFSecurityPolicy()
@property (readwrite, nonatomic, assign) AFSSLPinningMode SSLPinningMode; @property (readwrite, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
@property (readwrite, nonatomic, strong) NSSet *pinnedPublicKeys; @property (readwrite, nonatomic, strong) NSArray *pinnedPublicKeys;
@end @end
@implementation AFSecurityPolicy @implementation AFSecurityPolicy
+ (NSSet *)certificatesInBundle:(NSBundle *)bundle { + (NSArray *)defaultPinnedCertificates {
NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."]; static NSArray *_defaultPinnedCertificates = nil;
NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]];
for (NSString *path in paths) {
NSData *certificateData = [NSData dataWithContentsOfFile:path];
[certificates addObject:certificateData];
}
return [NSSet setWithSet:certificates];
}
+ (NSSet *)defaultPinnedCertificates {
static NSSet *_defaultPinnedCertificates = nil;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSBundle *bundle = [NSBundle bundleForClass:[self class]];
_defaultPinnedCertificates = [self certificatesInBundle:bundle]; 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];
}
_defaultPinnedCertificates = [[NSArray alloc] initWithArray:certificates];
}); });
return _defaultPinnedCertificates; return _defaultPinnedCertificates;
...@@ -177,19 +182,15 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { ...@@ -177,19 +182,15 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
} }
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode { + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode {
return [self policyWithPinningMode:pinningMode withPinnedCertificates:[self defaultPinnedCertificates]];
}
+ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates {
AFSecurityPolicy *securityPolicy = [[self alloc] init]; AFSecurityPolicy *securityPolicy = [[self alloc] init];
securityPolicy.SSLPinningMode = pinningMode; securityPolicy.SSLPinningMode = pinningMode;
[securityPolicy setPinnedCertificates:pinnedCertificates]; [securityPolicy setPinnedCertificates:[self defaultPinnedCertificates]];
return securityPolicy; return securityPolicy;
} }
- (instancetype)init { - (id)init {
self = [super init]; self = [super init];
if (!self) { if (!self) {
return nil; return nil;
...@@ -200,11 +201,11 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { ...@@ -200,11 +201,11 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
return self; return self;
} }
- (void)setPinnedCertificates:(NSSet *)pinnedCertificates { - (void)setPinnedCertificates:(NSArray *)pinnedCertificates {
_pinnedCertificates = pinnedCertificates; _pinnedCertificates = [[NSOrderedSet orderedSetWithArray:pinnedCertificates] array];
if (self.pinnedCertificates) { if (self.pinnedCertificates) {
NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]]; NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]];
for (NSData *certificate in self.pinnedCertificates) { for (NSData *certificate in self.pinnedCertificates) {
id publicKey = AFPublicKeyForCertificate(certificate); id publicKey = AFPublicKeyForCertificate(certificate);
if (!publicKey) { if (!publicKey) {
...@@ -212,7 +213,7 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { ...@@ -212,7 +213,7 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
} }
[mutablePinnedPublicKeys addObject:publicKey]; [mutablePinnedPublicKeys addObject:publicKey];
} }
self.pinnedPublicKeys = [NSSet setWithSet:mutablePinnedPublicKeys]; self.pinnedPublicKeys = [NSArray arrayWithArray:mutablePinnedPublicKeys];
} else { } else {
self.pinnedPublicKeys = nil; self.pinnedPublicKeys = nil;
} }
...@@ -220,6 +221,10 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { ...@@ -220,6 +221,10 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
#pragma mark - #pragma mark -
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust {
return [self evaluateServerTrust:serverTrust forDomain:nil];
}
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(NSString *)domain forDomain:(NSString *)domain
{ {
...@@ -251,6 +256,7 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { ...@@ -251,6 +256,7 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
return NO; return NO;
} }
NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
switch (self.SSLPinningMode) { switch (self.SSLPinningMode) {
case AFSSLPinningModeNone: case AFSSLPinningModeNone:
default: default:
...@@ -266,16 +272,13 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { ...@@ -266,16 +272,13 @@ static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
return NO; return NO;
} }
// obtain the chain after being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA) NSUInteger trustedCertificateCount = 0;
NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust); for (NSData *trustChainCertificate in serverCertificates) {
for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
if ([self.pinnedCertificates containsObject:trustChainCertificate]) { if ([self.pinnedCertificates containsObject:trustChainCertificate]) {
return YES; trustedCertificateCount++;
} }
} }
return trustedCertificateCount > 0;
return NO;
} }
case AFSSLPinningModePublicKey: { case AFSSLPinningModePublicKey: {
NSUInteger trustedPublicKeyCount = 0; NSUInteger trustedPublicKeyCount = 0;
......
// AFURLRequestSerialization.h // AFURLRequestSerialization.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -20,9 +20,7 @@ ...@@ -20,9 +20,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TargetConditionals.h> #if TARGET_OS_IOS
#if TARGET_OS_IOS || TARGET_OS_TV
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#elif TARGET_OS_WATCH #elif TARGET_OS_WATCH
#import <WatchKit/WatchKit.h> #import <WatchKit/WatchKit.h>
...@@ -31,31 +29,6 @@ ...@@ -31,31 +29,6 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
/** /**
Returns a percent-escaped string following RFC 3986 for a query string key or value.
RFC 3986 states that the following characters are "reserved" characters.
- General Delimiters: ":", "#", "[", "]", "@", "?", "/"
- Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
should be percent-escaped in the query string.
@param string The string to be percent-escaped.
@return The percent-escaped string.
*/
FOUNDATION_EXPORT NSString * AFPercentEscapedStringFromString(NSString *string);
/**
A helper method to generate encoded url query parameters for appending to the end of a URL.
@param parameters A dictionary of key/values to be encoded.
@return A url encoded query string
*/
FOUNDATION_EXPORT NSString * AFQueryStringFromParameters(NSDictionary *parameters);
/**
The `AFURLRequestSerialization` protocol is adopted by an object that encodes parameters for a specified HTTP requests. Request serializers may encode parameters as query strings, HTTP bodies, setting the appropriate HTTP header fields as necessary. The `AFURLRequestSerialization` protocol is adopted by an object that encodes parameters for a specified HTTP requests. Request serializers may encode parameters as query strings, HTTP bodies, setting the appropriate HTTP header fields as necessary.
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`. 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`.
...@@ -73,8 +46,11 @@ FOUNDATION_EXPORT NSString * AFQueryStringFromParameters(NSDictionary *parameter ...@@ -73,8 +46,11 @@ FOUNDATION_EXPORT NSString * AFQueryStringFromParameters(NSDictionary *parameter
*/ */
- (nullable NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request - (nullable NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
withParameters:(nullable id)parameters withParameters:(nullable id)parameters
error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW; error:(NSError * __nullable __autoreleasing *)error
#ifdef NS_SWIFT_NOTHROW
NS_SWIFT_NOTHROW
#endif
;
@end @end
#pragma mark - #pragma mark -
...@@ -154,7 +130,7 @@ typedef NS_ENUM(NSUInteger, AFHTTPRequestQueryStringSerializationStyle) { ...@@ -154,7 +130,7 @@ typedef NS_ENUM(NSUInteger, AFHTTPRequestQueryStringSerializationStyle) {
@discussion To add or remove default request headers, use `setValue:forHTTPHeaderField:`. @discussion To add or remove default request headers, use `setValue:forHTTPHeaderField:`.
*/ */
@property (readonly, nonatomic, strong) NSDictionary <NSString *, NSString *> *HTTPRequestHeaders; @property (readonly, nonatomic, strong) NSDictionary *HTTPRequestHeaders;
/** /**
Creates and returns a serializer with default configuration. Creates and returns a serializer with default configuration.
...@@ -189,6 +165,12 @@ forHTTPHeaderField:(NSString *)field; ...@@ -189,6 +165,12 @@ forHTTPHeaderField:(NSString *)field;
password:(NSString *)password; password:(NSString *)password;
/** /**
@deprecated This method has been deprecated. Use -setValue:forHTTPHeaderField: instead.
*/
- (void)setAuthorizationHeaderFieldWithToken:(NSString *)token DEPRECATED_ATTRIBUTE;
/**
Clears any existing value for the "Authorization" HTTP header. Clears any existing value for the "Authorization" HTTP header.
*/ */
- (void)clearAuthorizationHeader; - (void)clearAuthorizationHeader;
...@@ -200,7 +182,7 @@ forHTTPHeaderField:(NSString *)field; ...@@ -200,7 +182,7 @@ forHTTPHeaderField:(NSString *)field;
/** /**
HTTP methods for which serialized requests will encode parameters as a query string. `GET`, `HEAD`, and `DELETE` by default. HTTP methods for which serialized requests will encode parameters as a query string. `GET`, `HEAD`, and `DELETE` by default.
*/ */
@property (nonatomic, strong) NSSet <NSString *> *HTTPMethodsEncodingParametersInURI; @property (nonatomic, strong) NSSet *HTTPMethodsEncodingParametersInURI;
/** /**
Set the method of query string serialization according to one of the pre-defined styles. Set the method of query string serialization according to one of the pre-defined styles.
...@@ -223,6 +205,13 @@ forHTTPHeaderField:(NSString *)field; ...@@ -223,6 +205,13 @@ forHTTPHeaderField:(NSString *)field;
///------------------------------- ///-------------------------------
/** /**
@deprecated This method has been deprecated. Use -requestWithMethod:URLString:parameters:error: instead.
*/
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters DEPRECATED_ATTRIBUTE;
/**
Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string. Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string.
If the HTTP method is `GET`, `HEAD`, or `DELETE`, the parameters will be used to construct a url-encoded query string that is appended to the request's URL. Otherwise, the parameters will be encoded according to the value of the `parameterEncoding` property, and set as the request body. If the HTTP method is `GET`, `HEAD`, or `DELETE`, the parameters will be used to construct a url-encoded query string that is appended to the request's URL. Otherwise, the parameters will be encoded according to the value of the `parameterEncoding` property, and set as the request body.
...@@ -237,7 +226,15 @@ forHTTPHeaderField:(NSString *)field; ...@@ -237,7 +226,15 @@ forHTTPHeaderField:(NSString *)field;
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method - (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString URLString:(NSString *)URLString
parameters:(nullable id)parameters parameters:(nullable id)parameters
error:(NSError * _Nullable __autoreleasing *)error; error:(NSError * __nullable __autoreleasing *)error;
/**
@deprecated This method has been deprecated. Use -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error: instead.
*/
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block DEPRECATED_ATTRIBUTE;
/** /**
Creates an `NSMutableURLRequest` object with the specified HTTP method and URLString, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2 Creates an `NSMutableURLRequest` object with the specified HTTP method and URLString, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2
...@@ -254,9 +251,9 @@ forHTTPHeaderField:(NSString *)field; ...@@ -254,9 +251,9 @@ forHTTPHeaderField:(NSString *)field;
*/ */
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
URLString:(NSString *)URLString URLString:(NSString *)URLString
parameters:(nullable NSDictionary <NSString *, id> *)parameters parameters:(nullable NSDictionary *)parameters
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
error:(NSError * _Nullable __autoreleasing *)error; error:(NSError * __nullable __autoreleasing *)error;
/** /**
Creates an `NSMutableURLRequest` by removing the `HTTPBodyStream` from a request, and asynchronously writing its contents into the specified file, invoking the completion handler when finished. Creates an `NSMutableURLRequest` by removing the `HTTPBodyStream` from a request, and asynchronously writing its contents into the specified file, invoking the completion handler when finished.
...@@ -271,7 +268,7 @@ forHTTPHeaderField:(NSString *)field; ...@@ -271,7 +268,7 @@ forHTTPHeaderField:(NSString *)field;
*/ */
- (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request - (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request
writingStreamContentsToFile:(NSURL *)fileURL writingStreamContentsToFile:(NSURL *)fileURL
completionHandler:(nullable void (^)(NSError * _Nullable error))handler; completionHandler:(nullable void (^)(NSError * __nullable error))handler;
@end @end
...@@ -295,7 +292,7 @@ forHTTPHeaderField:(NSString *)field; ...@@ -295,7 +292,7 @@ forHTTPHeaderField:(NSString *)field;
*/ */
- (BOOL)appendPartWithFileURL:(NSURL *)fileURL - (BOOL)appendPartWithFileURL:(NSURL *)fileURL
name:(NSString *)name name:(NSString *)name
error:(NSError * _Nullable __autoreleasing *)error; error:(NSError * __nullable __autoreleasing *)error;
/** /**
Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary.
...@@ -312,7 +309,7 @@ forHTTPHeaderField:(NSString *)field; ...@@ -312,7 +309,7 @@ forHTTPHeaderField:(NSString *)field;
name:(NSString *)name name:(NSString *)name
fileName:(NSString *)fileName fileName:(NSString *)fileName
mimeType:(NSString *)mimeType mimeType:(NSString *)mimeType
error:(NSError * _Nullable __autoreleasing *)error; error:(NSError * __nullable __autoreleasing *)error;
/** /**
Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the data from the input stream and the multipart form boundary. Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the data from the input stream and the multipart form boundary.
...@@ -359,7 +356,7 @@ forHTTPHeaderField:(NSString *)field; ...@@ -359,7 +356,7 @@ forHTTPHeaderField:(NSString *)field;
@param headers The HTTP headers to be appended to the form data. @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. This parameter must not be `nil`. @param body The data to be encoded and appended to the form data. This parameter must not be `nil`.
*/ */
- (void)appendPartWithHeaders:(nullable NSDictionary <NSString *, NSString *> *)headers - (void)appendPartWithHeaders:(nullable NSDictionary *)headers
body:(NSData *)body; body:(NSData *)body;
/** /**
......
// AFURLResponseSerialization.h // AFURLResponseSerialization.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -42,7 +42,11 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -42,7 +42,11 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
- (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response - (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response
data:(nullable NSData *)data data:(nullable NSData *)data
error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW; error:(NSError * __nullable __autoreleasing *)error
#ifdef NS_SWIFT_NOTHROW
NS_SWIFT_NOTHROW
#endif
;
@end @end
...@@ -57,7 +61,10 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -57,7 +61,10 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init; - (instancetype)init;
@property (nonatomic, assign) NSStringEncoding stringEncoding DEPRECATED_MSG_ATTRIBUTE("The string encoding is never used. AFHTTPResponseSerializer only validates status codes and content types but does not try to decode the received data in any way."); /**
The string encoding used to serialize data received from the server, when no string encoding is specified by the response. `NSUTF8StringEncoding` by default.
*/
@property (nonatomic, assign) NSStringEncoding stringEncoding;
/** /**
Creates and returns a serializer with default configuration. Creates and returns a serializer with default configuration.
...@@ -78,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -78,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
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. 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, copy, nullable) NSSet <NSString *> *acceptableContentTypes; @property (nonatomic, copy, nullable) NSSet *acceptableContentTypes;
/** /**
Validates the specified response and data. Validates the specified response and data.
...@@ -93,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -93,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
- (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response - (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response
data:(nullable NSData *)data data:(nullable NSData *)data
error:(NSError * _Nullable __autoreleasing *)error; error:(NSError * __nullable __autoreleasing *)error;
@end @end
...@@ -108,8 +115,6 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -108,8 +115,6 @@ NS_ASSUME_NONNULL_BEGIN
- `application/json` - `application/json`
- `text/json` - `text/json`
- `text/javascript` - `text/javascript`
In RFC 7159 - Section 8.1, it states that JSON text is required to be encoded in UTF-8, UTF-16, or UTF-32, and the default encoding is UTF-8. NSJSONSerialization provides support for all the encodings listed in the specification, and recommends UTF-8 for efficiency. Using an unsupported encoding will result in serialization error. See the `NSJSONSerialization` documentation for more details.
*/ */
@interface AFJSONResponseSerializer : AFHTTPResponseSerializer @interface AFJSONResponseSerializer : AFHTTPResponseSerializer
...@@ -165,7 +170,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -165,7 +170,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init; - (instancetype)init;
/** /**
Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSXMLDocument` documentation section "Input and Output Options". `0` by default. Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default.
*/ */
@property (nonatomic, assign) NSUInteger options; @property (nonatomic, assign) NSUInteger options;
...@@ -234,7 +239,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -234,7 +239,7 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@interface AFImageResponseSerializer : AFHTTPResponseSerializer @interface AFImageResponseSerializer : AFHTTPResponseSerializer
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
/** /**
The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance. The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance.
*/ */
...@@ -258,14 +263,14 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -258,14 +263,14 @@ NS_ASSUME_NONNULL_BEGIN
/** /**
The component response serializers. The component response serializers.
*/ */
@property (readonly, nonatomic, copy) NSArray <id<AFURLResponseSerialization>> *responseSerializers; @property (readonly, nonatomic, copy) NSArray *responseSerializers;
/** /**
Creates and returns a compound serializer comprised of the specified response serializers. Creates and returns a compound serializer comprised of the specified response serializers.
@warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`. @warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`.
*/ */
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray <id<AFURLResponseSerialization>> *)responseSerializers; + (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers;
@end @end
......
Copyright (c) 2011-2016 Alamofire Software Foundation (http://alamofire.org/) Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
// AFAutoPurgingImageCache.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <TargetConditionals.h>
#import <Foundation/Foundation.h>
#if TARGET_OS_IOS || TARGET_OS_TV
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
The `AFImageCache` protocol defines a set of APIs for adding, removing and fetching images from a cache synchronously.
*/
@protocol AFImageCache <NSObject>
/**
Adds the image to the cache with the given identifier.
@param image The image to cache.
@param identifier The unique identifier for the image in the cache.
*/
- (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier;
/**
Removes the image from the cache matching the given identifier.
@param identifier The unique identifier for the image in the cache.
@return A BOOL indicating whether or not the image was removed from the cache.
*/
- (BOOL)removeImageWithIdentifier:(NSString *)identifier;
/**
Removes all images from the cache.
@return A BOOL indicating whether or not all images were removed from the cache.
*/
- (BOOL)removeAllImages;
/**
Returns the image in the cache associated with the given identifier.
@param identifier The unique identifier for the image in the cache.
@return An image for the matching identifier, or nil.
*/
- (nullable UIImage *)imageWithIdentifier:(NSString *)identifier;
@end
/**
The `ImageRequestCache` protocol extends the `ImageCache` protocol by adding methods for adding, removing and fetching images from a cache given an `NSURLRequest` and additional identifier.
*/
@protocol AFImageRequestCache <AFImageCache>
/**
Asks if the image should be cached using an identifier created from the request and additional identifier.
@param image The image to be cached.
@param request The unique URL request identifing the image asset.
@param identifier The additional identifier to apply to the URL request to identify the image.
@return A BOOL indicating whether or not the image should be added to the cache. YES will cache, NO will prevent caching.
*/
- (BOOL)shouldCacheImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
/**
Adds the image to the cache using an identifier created from the request and additional identifier.
@param image The image to cache.
@param request The unique URL request identifing the image asset.
@param identifier The additional identifier to apply to the URL request to identify the image.
*/
- (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
/**
Removes the image from the cache using an identifier created from the request and additional identifier.
@param request The unique URL request identifing the image asset.
@param identifier The additional identifier to apply to the URL request to identify the image.
@return A BOOL indicating whether or not all images were removed from the cache.
*/
- (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
/**
Returns the image from the cache associated with an identifier created from the request and additional identifier.
@param request The unique URL request identifing the image asset.
@param identifier The additional identifier to apply to the URL request to identify the image.
@return An image for the matching request and identifier, or nil.
*/
- (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier;
@end
/**
The `AutoPurgingImageCache` in an in-memory image cache used to store images up to a given memory capacity. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated.
*/
@interface AFAutoPurgingImageCache : NSObject <AFImageRequestCache>
/**
The total memory capacity of the cache in bytes.
*/
@property (nonatomic, assign) UInt64 memoryCapacity;
/**
The preferred memory usage after purge in bytes. During a purge, images will be purged until the memory capacity drops below this limit.
*/
@property (nonatomic, assign) UInt64 preferredMemoryUsageAfterPurge;
/**
The current total memory usage in bytes of all images stored within the cache.
*/
@property (nonatomic, assign, readonly) UInt64 memoryUsage;
/**
Initialies the `AutoPurgingImageCache` instance with default values for memory capacity and preferred memory usage after purge limit. `memoryCapcity` defaults to `100 MB`. `preferredMemoryUsageAfterPurge` defaults to `60 MB`.
@return The new `AutoPurgingImageCache` instance.
*/
- (instancetype)init;
/**
Initialies the `AutoPurgingImageCache` instance with the given memory capacity and preferred memory usage
after purge limit.
@param memoryCapacity The total memory capacity of the cache in bytes.
@param preferredMemoryCapacity The preferred memory usage after purge in bytes.
@return The new `AutoPurgingImageCache` instance.
*/
- (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity;
@end
NS_ASSUME_NONNULL_END
#endif
// AFAutoPurgingImageCache.m
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <TargetConditionals.h>
#if TARGET_OS_IOS || TARGET_OS_TV
#import "AFAutoPurgingImageCache.h"
@interface AFCachedImage : NSObject
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) NSString *identifier;
@property (nonatomic, assign) UInt64 totalBytes;
@property (nonatomic, strong) NSDate *lastAccessDate;
@property (nonatomic, assign) UInt64 currentMemoryUsage;
@end
@implementation AFCachedImage
-(instancetype)initWithImage:(UIImage *)image identifier:(NSString *)identifier {
if (self = [self init]) {
self.image = image;
self.identifier = identifier;
CGSize imageSize = CGSizeMake(image.size.width * image.scale, image.size.height * image.scale);
CGFloat bytesPerPixel = 4.0;
CGFloat bytesPerSize = imageSize.width * imageSize.height;
self.totalBytes = (UInt64)bytesPerPixel * (UInt64)bytesPerSize;
self.lastAccessDate = [NSDate date];
}
return self;
}
- (UIImage*)accessImage {
self.lastAccessDate = [NSDate date];
return self.image;
}
- (NSString *)description {
NSString *descriptionString = [NSString stringWithFormat:@"Idenfitier: %@ lastAccessDate: %@ ", self.identifier, self.lastAccessDate];
return descriptionString;
}
@end
@interface AFAutoPurgingImageCache ()
@property (nonatomic, strong) NSMutableDictionary <NSString* , AFCachedImage*> *cachedImages;
@property (nonatomic, assign) UInt64 currentMemoryUsage;
@property (nonatomic, strong) dispatch_queue_t synchronizationQueue;
@end
@implementation AFAutoPurgingImageCache
- (instancetype)init {
return [self initWithMemoryCapacity:100 * 1024 * 1024 preferredMemoryCapacity:60 * 1024 * 1024];
}
- (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity {
if (self = [super init]) {
self.memoryCapacity = memoryCapacity;
self.preferredMemoryUsageAfterPurge = preferredMemoryCapacity;
self.cachedImages = [[NSMutableDictionary alloc] init];
NSString *queueName = [NSString stringWithFormat:@"com.alamofire.autopurgingimagecache-%@", [[NSUUID UUID] UUIDString]];
self.synchronizationQueue = dispatch_queue_create([queueName cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_CONCURRENT);
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(removeAllImages)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (UInt64)memoryUsage {
__block UInt64 result = 0;
dispatch_sync(self.synchronizationQueue, ^{
result = self.currentMemoryUsage;
});
return result;
}
- (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier {
dispatch_barrier_async(self.synchronizationQueue, ^{
AFCachedImage *cacheImage = [[AFCachedImage alloc] initWithImage:image identifier:identifier];
AFCachedImage *previousCachedImage = self.cachedImages[identifier];
if (previousCachedImage != nil) {
self.currentMemoryUsage -= previousCachedImage.totalBytes;
}
self.cachedImages[identifier] = cacheImage;
self.currentMemoryUsage += cacheImage.totalBytes;
});
dispatch_barrier_async(self.synchronizationQueue, ^{
if (self.currentMemoryUsage > self.memoryCapacity) {
UInt64 bytesToPurge = self.currentMemoryUsage - self.preferredMemoryUsageAfterPurge;
NSMutableArray <AFCachedImage*> *sortedImages = [NSMutableArray arrayWithArray:self.cachedImages.allValues];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastAccessDate"
ascending:YES];
[sortedImages sortUsingDescriptors:@[sortDescriptor]];
UInt64 bytesPurged = 0;
for (AFCachedImage *cachedImage in sortedImages) {
[self.cachedImages removeObjectForKey:cachedImage.identifier];
bytesPurged += cachedImage.totalBytes;
if (bytesPurged >= bytesToPurge) {
break ;
}
}
self.currentMemoryUsage -= bytesPurged;
}
});
}
- (BOOL)removeImageWithIdentifier:(NSString *)identifier {
__block BOOL removed = NO;
dispatch_barrier_sync(self.synchronizationQueue, ^{
AFCachedImage *cachedImage = self.cachedImages[identifier];
if (cachedImage != nil) {
[self.cachedImages removeObjectForKey:identifier];
self.currentMemoryUsage -= cachedImage.totalBytes;
removed = YES;
}
});
return removed;
}
- (BOOL)removeAllImages {
__block BOOL removed = NO;
dispatch_barrier_sync(self.synchronizationQueue, ^{
if (self.cachedImages.count > 0) {
[self.cachedImages removeAllObjects];
self.currentMemoryUsage = 0;
removed = YES;
}
});
return removed;
}
- (nullable UIImage *)imageWithIdentifier:(NSString *)identifier {
__block UIImage *image = nil;
dispatch_sync(self.synchronizationQueue, ^{
AFCachedImage *cachedImage = self.cachedImages[identifier];
image = [cachedImage accessImage];
});
return image;
}
- (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
[self addImage:image withIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
}
- (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
return [self removeImageWithIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
}
- (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier {
return [self imageWithIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]];
}
- (NSString *)imageCacheKeyFromURLRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)additionalIdentifier {
NSString *key = request.URL.absoluteString;
if (additionalIdentifier != nil) {
key = [key stringByAppendingString:additionalIdentifier];
}
return key;
}
- (BOOL)shouldCacheImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier {
return YES;
}
@end
#endif
// AFImageDownloader.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <TargetConditionals.h>
#if TARGET_OS_IOS || TARGET_OS_TV
#import <Foundation/Foundation.h>
#import "AFAutoPurgingImageCache.h"
#import "AFHTTPSessionManager.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, AFImageDownloadPrioritization) {
AFImageDownloadPrioritizationFIFO,
AFImageDownloadPrioritizationLIFO
};
/**
The `AFImageDownloadReceipt` is an object vended by the `AFImageDownloader` when starting a data task. It can be used to cancel active tasks running on the `AFImageDownloader` session. As a general rule, image data tasks should be cancelled using the `AFImageDownloadReceipt` instead of calling `cancel` directly on the `task` itself. The `AFImageDownloader` is optimized to handle duplicate task scenarios as well as pending versus active downloads.
*/
@interface AFImageDownloadReceipt : NSObject
/**
The data task created by the `AFImageDownloader`.
*/
@property (nonatomic, strong) NSURLSessionDataTask *task;
/**
The unique identifier for the success and failure blocks when duplicate requests are made.
*/
@property (nonatomic, strong) NSUUID *receiptID;
@end
/** The `AFImageDownloader` class is responsible for downloading images in parallel on a prioritized queue. Incoming downloads are added to the front or back of the queue depending on the download prioritization. Each downloaded image is cached in the underlying `NSURLCache` as well as the in-memory image cache. By default, any download request with a cached image equivalent in the image cache will automatically be served the cached image representation.
*/
@interface AFImageDownloader : NSObject
/**
The image cache used to store all downloaded images in. `AFAutoPurgingImageCache` by default.
*/
@property (nonatomic, strong, nullable) id <AFImageRequestCache> imageCache;
/**
The `AFHTTPSessionManager` used to download images. By default, this is configured with an `AFImageResponseSerializer`, and a shared `NSURLCache` for all image downloads.
*/
@property (nonatomic, strong) AFHTTPSessionManager *sessionManager;
/**
Defines the order prioritization of incoming download requests being inserted into the queue. `AFImageDownloadPrioritizationFIFO` by default.
*/
@property (nonatomic, assign) AFImageDownloadPrioritization downloadPrioritizaton;
/**
The shared default instance of `AFImageDownloader` initialized with default values.
*/
+ (instancetype)defaultInstance;
/**
Creates a default `NSURLCache` with common usage parameter values.
@returns The default `NSURLCache` instance.
*/
+ (NSURLCache *)defaultURLCache;
/**
The default `NSURLSessionConfiguration` with common usage parameter values.
*/
+ (NSURLSessionConfiguration *)defaultURLSessionConfiguration;
/**
Default initializer
@return An instance of `AFImageDownloader` initialized with default values.
*/
- (instancetype)init;
/**
Initializer with specific `URLSessionConfiguration`
@param configuration The `NSURLSessionConfiguration` to be be used
@return An instance of `AFImageDownloader` initialized with default values and custom `NSURLSessionConfiguration`
*/
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration;
/**
Initializes the `AFImageDownloader` instance with the given session manager, download prioritization, maximum active download count and image cache.
@param sessionManager The session manager to use to download images.
@param downloadPrioritization The download prioritization of the download queue.
@param maximumActiveDownloads The maximum number of active downloads allowed at any given time. Recommend `4`.
@param imageCache The image cache used to store all downloaded images in.
@return The new `AFImageDownloader` instance.
*/
- (instancetype)initWithSessionManager:(AFHTTPSessionManager *)sessionManager
downloadPrioritization:(AFImageDownloadPrioritization)downloadPrioritization
maximumActiveDownloads:(NSInteger)maximumActiveDownloads
imageCache:(nullable id <AFImageRequestCache>)imageCache;
/**
Creates a data task using the `sessionManager` instance for the specified URL request.
If the same data task is already in the queue or currently being downloaded, the success and failure blocks are
appended to the already existing task. Once the task completes, all success or failure blocks attached to the
task are executed in the order they were added.
@param request The URL request.
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
@return The image download receipt for the data task if available. `nil` if the image is stored in the cache.
cache and the URL request cache policy allows the cache to be used.
*/
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
/**
Creates a data task using the `sessionManager` instance for the specified URL request.
If the same data task is already in the queue or currently being downloaded, the success and failure blocks are
appended to the already existing task. Once the task completes, all success or failure blocks attached to the
task are executed in the order they were added.
@param request The URL request.
@param receiptID The identifier to use for the download receipt that will be created for this request. This must be a unique identifier that does not represent any other request.
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
@return The image download receipt for the data task if available. `nil` if the image is stored in the cache.
cache and the URL request cache policy allows the cache to be used.
*/
- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request
withReceiptID:(NSUUID *)receiptID
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
/**
Cancels the data task in the receipt by removing the corresponding success and failure blocks and cancelling the data task if necessary.
If the data task is pending in the queue, it will be cancelled if no other success and failure blocks are registered with the data task. If the data task is currently executing or is already completed, the success and failure blocks are removed and will not be called when the task finishes.
@param imageDownloadReceipt The image download receipt to cancel.
*/
- (void)cancelTaskForImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt;
@end
#endif
NS_ASSUME_NONNULL_END
// AFNetworkActivityIndicatorManager.h // AFNetworkActivityIndicatorManager.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -21,16 +21,16 @@ ...@@ -21,16 +21,16 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TargetConditionals.h> #import <Availability.h>
#if TARGET_OS_IOS #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
/** /**
`AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a session task has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero. `AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a network request operation has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code: You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code:
...@@ -52,25 +52,9 @@ NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropri ...@@ -52,25 +52,9 @@ NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropri
@property (nonatomic, assign, getter = isEnabled) BOOL enabled; @property (nonatomic, assign, getter = isEnabled) BOOL enabled;
/** /**
A Boolean value indicating whether the network activity indicator manager is currently active. A Boolean value indicating whether the network activity indicator is currently displayed in the status bar.
*/
@property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
/**
A time interval indicating the minimum duration of networking activity that should occur before the activity indicator is displayed. The default value 1 second. If the network activity indicator should be displayed immediately when network activity occurs, this value should be set to 0 seconds.
Apple's HIG describes the following:
> Display the network activity indicator to provide feedback when your app accesses the network for more than a couple of seconds. If the operation finishes sooner than that, you don’t have to show the network activity indicator, because the indicator is likely to disappear before users notice its presence.
*/
@property (nonatomic, assign) NSTimeInterval activationDelay;
/**
A time interval indicating the duration of time of no networking activity required before the activity indicator is disabled. This allows for continuous display of the network activity indicator across multiple requests. The default value is 0.17 seconds.
*/ */
@property (readonly, nonatomic, assign) BOOL isNetworkActivityIndicatorVisible;
@property (nonatomic, assign) NSTimeInterval completionDelay;
/** /**
Returns the shared network activity indicator manager object for the system. Returns the shared network activity indicator manager object for the system.
...@@ -89,13 +73,6 @@ NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropri ...@@ -89,13 +73,6 @@ NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropri
*/ */
- (void)decrementActivityCount; - (void)decrementActivityCount;
/**
Set the a custom method to be executed when the network activity indicator manager should be hidden/shown. By default, this is null, and the UIApplication Network Activity Indicator will be managed automatically. If this block is set, it is the responsiblity of the caller to manager the network activity indicator going forward.
@param block A block to be executed when the network activity indicator status changes.
*/
- (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
......
// UIActivityIndicatorView+AFNetworking.h // UIActivityIndicatorView+AFNetworking.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -21,14 +21,16 @@ ...@@ -21,14 +21,16 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TargetConditionals.h> #import <Availability.h>
#if TARGET_OS_IOS || TARGET_OS_TV #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@class AFURLConnectionOperation;
/** /**
This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a session task. This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a request operation or session task.
*/ */
@interface UIActivityIndicatorView (AFNetworking) @interface UIActivityIndicatorView (AFNetworking)
...@@ -41,7 +43,20 @@ ...@@ -41,7 +43,20 @@
@param task The task. If `nil`, automatic updating from any previously specified operation will be disabled. @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
*/ */
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task; - (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task;
#endif
///---------------------------------------
/// @name Animating for Request Operations
///---------------------------------------
/**
Binds the animating state to the execution state of the specified operation.
@param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled.
*/
- (void)setAnimatingWithStateOfOperation:(nullable AFURLConnectionOperation *)operation;
@end @end
......
// UIActivityIndicatorView+AFNetworking.m // UIActivityIndicatorView+AFNetworking.m
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -22,15 +22,22 @@ ...@@ -22,15 +22,22 @@
#import "UIActivityIndicatorView+AFNetworking.h" #import "UIActivityIndicatorView+AFNetworking.h"
#import <objc/runtime.h> #import <objc/runtime.h>
#if TARGET_OS_IOS || TARGET_OS_TV #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import "AFHTTPRequestOperation.h"
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
#import "AFURLSessionManager.h" #import "AFURLSessionManager.h"
#endif
@interface AFActivityIndicatorViewNotificationObserver : NSObject @interface AFActivityIndicatorViewNotificationObserver : NSObject
@property (readonly, nonatomic, weak) UIActivityIndicatorView *activityIndicatorView; @property (readonly, nonatomic, weak) UIActivityIndicatorView *activityIndicatorView;
- (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView; - (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView;
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task; - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task;
#endif
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation;
@end @end
...@@ -45,9 +52,15 @@ ...@@ -45,9 +52,15 @@
return notificationObserver; return notificationObserver;
} }
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task { - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task {
[[self af_notificationObserver] setAnimatingWithStateOfTask:task]; [[self af_notificationObserver] setAnimatingWithStateOfTask:task];
} }
#endif
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation {
[[self af_notificationObserver] setAnimatingWithStateOfOperation:operation];
}
@end @end
...@@ -62,6 +75,7 @@ ...@@ -62,6 +75,7 @@
return self; return self;
} }
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task { - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
...@@ -71,12 +85,16 @@ ...@@ -71,12 +85,16 @@
if (task) { if (task) {
if (task.state != NSURLSessionTaskStateCompleted) { if (task.state != NSURLSessionTaskStateCompleted) {
UIActivityIndicatorView *activityIndicatorView = self.activityIndicatorView;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
if (task.state == NSURLSessionTaskStateRunning) { if (task.state == NSURLSessionTaskStateRunning) {
[activityIndicatorView startAnimating]; [self.activityIndicatorView startAnimating];
} else { } else {
[activityIndicatorView stopAnimating]; [self.activityIndicatorView stopAnimating];
} }
#pragma clang diagnostic pop
[notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingTaskDidResumeNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingTaskDidResumeNotification object:task];
[notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidCompleteNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidCompleteNotification object:task];
...@@ -84,18 +102,52 @@ ...@@ -84,18 +102,52 @@
} }
} }
} }
#endif
#pragma mark -
- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
if (operation) {
if (![operation isFinished]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
if ([operation isExecuting]) {
[self.activityIndicatorView startAnimating];
} else {
[self.activityIndicatorView stopAnimating];
}
#pragma clang diagnostic pop
[notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingOperationDidStartNotification object:operation];
[notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingOperationDidFinishNotification object:operation];
}
}
}
#pragma mark - #pragma mark -
- (void)af_startAnimating { - (void)af_startAnimating {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
[self.activityIndicatorView startAnimating]; [self.activityIndicatorView startAnimating];
#pragma clang diagnostic pop
}); });
} }
- (void)af_stopAnimating { - (void)af_stopAnimating {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
[self.activityIndicatorView stopAnimating]; [self.activityIndicatorView stopAnimating];
#pragma clang diagnostic pop
}); });
} }
...@@ -104,9 +156,14 @@ ...@@ -104,9 +156,14 @@
- (void)dealloc { - (void)dealloc {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
[notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
#endif
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
} }
@end @end
......
// UIAlertView+AFNetworking.h
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import <Availability.h>
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class AFURLConnectionOperation;
/**
This category adds methods to the UIKit framework's `UIAlertView` class. The methods in this category provide support for automatically showing an alert if a session task or request operation finishes with an error. Alert title and message are filled from the corresponding `localizedDescription` & `localizedRecoverySuggestion` or `localizedFailureReason` of the error.
*/
@interface UIAlertView (AFNetworking)
///-------------------------------------
/// @name Showing Alert for Session Task
///-------------------------------------
/**
Shows an alert view with the error of the specified session task, if any.
@param task The session task.
@param delegate The alert view delegate.
*/
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
delegate:(nullable id)delegate NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
#endif
/**
Shows an alert view with the error of the specified session task, if any, with a custom cancel button title and other button titles.
@param task The session task.
@param delegate The alert view delegate.
@param cancelButtonTitle The title of the cancel button or nil if there is no cancel button. Using this argument is equivalent to setting the cancel button index to the value returned by invoking addButtonWithTitle: specifying this title.
@param otherButtonTitles The title of another button. Using this argument is equivalent to invoking addButtonWithTitle: with this title to add more buttons. Too many buttons can cause the alert view to scroll. For guidelines on the best ways to use an alert in an app, see "Temporary Views". Titles of additional buttons to add to the receiver, terminated with `nil`.
*/
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
delegate:(nullable id)delegate
cancelButtonTitle:(nullable NSString *)cancelButtonTitle
otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
#endif
///------------------------------------------
/// @name Showing Alert for Request Operation
///------------------------------------------
/**
Shows an alert view with the error of the specified request operation, if any.
@param operation The request operation.
@param delegate The alert view delegate.
*/
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
delegate:(nullable id)delegate NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
/**
Shows an alert view with the error of the specified request operation, if any, with a custom cancel button title and other button titles.
@param operation The request operation.
@param delegate The alert view delegate.
@param cancelButtonTitle The title of the cancel button or nil if there is no cancel button. Using this argument is equivalent to setting the cancel button index to the value returned by invoking addButtonWithTitle: specifying this title.
@param otherButtonTitles The title of another button. Using this argument is equivalent to invoking addButtonWithTitle: with this title to add more buttons. Too many buttons can cause the alert view to scroll. For guidelines on the best ways to use an alert in an app, see "Temporary Views". Titles of additional buttons to add to the receiver, terminated with `nil`.
*/
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
delegate:(nullable id)delegate
cancelButtonTitle:(nullable NSString *)cancelButtonTitle
otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions.");
@end
NS_ASSUME_NONNULL_END
#endif
// UIAlertView+AFNetworking.m
// Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "UIAlertView+AFNetworking.h"
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import "AFURLConnectionOperation.h"
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
#import "AFURLSessionManager.h"
#endif
static void AFGetAlertViewTitleAndMessageFromError(NSError *error, NSString * __autoreleasing *title, NSString * __autoreleasing *message) {
if (error.localizedDescription && (error.localizedRecoverySuggestion || error.localizedFailureReason)) {
*title = error.localizedDescription;
if (error.localizedRecoverySuggestion) {
*message = error.localizedRecoverySuggestion;
} else {
*message = error.localizedFailureReason;
}
} else if (error.localizedDescription) {
*title = NSLocalizedStringFromTable(@"Error", @"AFNetworking", @"Fallback Error Description");
*message = error.localizedDescription;
} else {
*title = NSLocalizedStringFromTable(@"Error", @"AFNetworking", @"Fallback Error Description");
*message = [NSString stringWithFormat:NSLocalizedStringFromTable(@"%@ Error: %ld", @"AFNetworking", @"Fallback Error Failure Reason Format"), error.domain, (long)error.code];
}
}
@implementation UIAlertView (AFNetworking)
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
delegate:(id)delegate
{
[self showAlertViewForTaskWithErrorOnCompletion:task delegate:delegate cancelButtonTitle:NSLocalizedStringFromTable(@"Dismiss", @"AFNetworking", @"UIAlertView Cancel Button Title") otherButtonTitles:nil, nil];
}
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION
{
NSMutableArray *mutableOtherTitles = [NSMutableArray array];
va_list otherButtonTitleList;
va_start(otherButtonTitleList, otherButtonTitles);
{
for (NSString *otherButtonTitle = otherButtonTitles; otherButtonTitle != nil; otherButtonTitle = va_arg(otherButtonTitleList, NSString *)) {
[mutableOtherTitles addObject:otherButtonTitle];
}
}
va_end(otherButtonTitleList);
__block __weak id<NSObject> observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingTaskDidCompleteNotification object:task queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) {
NSError *error = notification.userInfo[AFNetworkingTaskDidCompleteErrorKey];
if (error) {
NSString *title, *message;
AFGetAlertViewTitleAndMessageFromError(error, &title, &message);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil];
for (NSString *otherButtonTitle in mutableOtherTitles) {
[alertView addButtonWithTitle:otherButtonTitle];
}
[alertView setTitle:title];
[alertView setMessage:message];
[alertView show];
}
[[NSNotificationCenter defaultCenter] removeObserver:observer];
}];
}
#endif
#pragma mark -
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
delegate:(id)delegate
{
[self showAlertViewForRequestOperationWithErrorOnCompletion:operation delegate:delegate cancelButtonTitle:NSLocalizedStringFromTable(@"Dismiss", @"AFNetworking", @"UIAlertView Cancel Button Title") otherButtonTitles:nil, nil];
}
+ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation
delegate:(id)delegate
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION
{
NSMutableArray *mutableOtherTitles = [NSMutableArray array];
va_list otherButtonTitleList;
va_start(otherButtonTitleList, otherButtonTitles);
{
for (NSString *otherButtonTitle = otherButtonTitles; otherButtonTitle != nil; otherButtonTitle = va_arg(otherButtonTitleList, NSString *)) {
[mutableOtherTitles addObject:otherButtonTitle];
}
}
va_end(otherButtonTitleList);
__block __weak id<NSObject> observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingOperationDidFinishNotification object:operation queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) {
if (notification.object && [notification.object isKindOfClass:[AFURLConnectionOperation class]]) {
NSError *error = [(AFURLConnectionOperation *)notification.object error];
if (error) {
NSString *title, *message;
AFGetAlertViewTitleAndMessageFromError(error, &title, &message);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil];
for (NSString *otherButtonTitle in mutableOtherTitles) {
[alertView addButtonWithTitle:otherButtonTitle];
}
[alertView setTitle:title];
[alertView setMessage:message];
[alertView show];
}
}
[[NSNotificationCenter defaultCenter] removeObserver:observer];
}];
}
@end
#endif
// UIButton+AFNetworking.h // UIButton+AFNetworking.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -21,15 +21,15 @@ ...@@ -21,15 +21,15 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TargetConditionals.h> #import <Availability.h>
#if TARGET_OS_IOS || TARGET_OS_TV #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class AFImageDownloader; @protocol AFURLResponseSerialization, AFImageCache;
/** /**
This category adds methods to the UIKit framework's `UIButton` class. The methods in this category provide support for loading remote images and background images asynchronously from a URL. This category adds methods to the UIKit framework's `UIButton` class. The methods in this category provide support for loading remote images and background images asynchronously from a URL.
...@@ -38,21 +38,32 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -38,21 +38,32 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@interface UIButton (AFNetworking) @interface UIButton (AFNetworking)
///------------------------------------ ///----------------------------
/// @name Accessing the Image Downloader /// @name Accessing Image Cache
///------------------------------------ ///----------------------------
/**
The image cache used to improve image loading performance on scroll views. By default, `UIButton` will use the `sharedImageCache` of `UIImageView`.
*/
+ (id <AFImageCache>)sharedImageCache;
/** /**
Set the shared image downloader used to download images. Set the cache used for image loading.
@param imageDownloader The shared image downloader used to download images. @param imageCache The image cache.
*/ */
+ (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader; + (void)setSharedImageCache:(__nullable id <AFImageCache>)imageCache;
///------------------------------------
/// @name Accessing Response Serializer
///------------------------------------
/** /**
The shared image downloader used to download images. The response serializer used to create an image representation from the server response and response data. By default, this is an instance of `AFImageResponseSerializer`.
@discussion Subclasses of `AFImageResponseSerializer` could be used to perform post-processing, such as color correction, face detection, or other effects. See https://github.com/AFNetworking/AFCoreImageSerializer
*/ */
+ (AFImageDownloader *)sharedImageDownloader; @property (nonatomic, strong) id <AFURLResponseSerialization> imageResponseSerializer;
///-------------------- ///--------------------
/// @name Setting Image /// @name Setting Image
...@@ -92,14 +103,14 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -92,14 +103,14 @@ NS_ASSUME_NONNULL_BEGIN
@param state The control state. @param state The control state.
@param urlRequest The URL request used for the image request. @param urlRequest The URL request used for the image request.
@param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the button will not change its image until the image request finishes. @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the button will not change its image until the image request finishes.
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. @param success A block to be executed when the image request operation finishes successfully. This block has no return value and takes two arguments: the server response and the image. If the image was returned from cache, the response parameter will be `nil`.
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. @param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes a single argument: the error that occurred.
*/ */
- (void)setImageForState:(UIControlState)state - (void)setImageForState:(UIControlState)state
withURLRequest:(NSURLRequest *)urlRequest withURLRequest:(NSURLRequest *)urlRequest
placeholderImage:(nullable UIImage *)placeholderImage placeholderImage:(nullable UIImage *)placeholderImage
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; failure:(nullable void (^)(NSError *error))failure;
///------------------------------- ///-------------------------------
...@@ -140,14 +151,14 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -140,14 +151,14 @@ NS_ASSUME_NONNULL_BEGIN
@param state The control state. @param state The control state.
@param urlRequest The URL request used for the image request. @param urlRequest The URL request used for the image request.
@param placeholderImage The background image to be set initially, until the background image request finishes. If `nil`, the button will not change its background image until the background image request finishes. @param placeholderImage The background image to be set initially, until the background image request finishes. If `nil`, the button will not change its background image until the background image request finishes.
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. @param success A block to be executed when the image request operation finishes successfully. This block has no return value and takes two arguments: the server response and the image. If the image was returned from cache, the response parameter will be `nil`.
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. @param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes a single argument: the error that occurred.
*/ */
- (void)setBackgroundImageForState:(UIControlState)state - (void)setBackgroundImageForState:(UIControlState)state
withURLRequest:(NSURLRequest *)urlRequest withURLRequest:(NSURLRequest *)urlRequest
placeholderImage:(nullable UIImage *)placeholderImage placeholderImage:(nullable UIImage *)placeholderImage
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; failure:(nullable void (^)(NSError *error))failure;
///------------------------------ ///------------------------------
...@@ -155,18 +166,18 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -155,18 +166,18 @@ NS_ASSUME_NONNULL_BEGIN
///------------------------------ ///------------------------------
/** /**
Cancels any executing image task for the specified control state of the receiver, if one exists. Cancels any executing image operation for the specified control state of the receiver, if one exists.
@param state The control state. @param state The control state.
*/ */
- (void)cancelImageDownloadTaskForState:(UIControlState)state; - (void)cancelImageRequestOperationForState:(UIControlState)state;
/** /**
Cancels any executing background image task for the specified control state of the receiver, if one exists. Cancels any executing background image operation for the specified control state of the receiver, if one exists.
@param state The control state. @param state The control state.
*/ */
- (void)cancelBackgroundImageDownloadTaskForState:(UIControlState)state; - (void)cancelBackgroundImageRequestOperationForState:(UIControlState)state;
@end @end
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#if TARGET_OS_IOS || TARGET_OS_TV #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
......
// UIImageView+AFNetworking.h // UIImageView+AFNetworking.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -21,36 +21,47 @@ ...@@ -21,36 +21,47 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TargetConditionals.h> #import <Availability.h>
#if TARGET_OS_IOS || TARGET_OS_TV #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class AFImageDownloader; @protocol AFURLResponseSerialization, AFImageCache;
/** /**
This category adds methods to the UIKit framework's `UIImageView` class. The methods in this category provide support for loading remote images asynchronously from a URL. This category adds methods to the UIKit framework's `UIImageView` class. The methods in this category provide support for loading remote images asynchronously from a URL.
*/ */
@interface UIImageView (AFNetworking) @interface UIImageView (AFNetworking)
///------------------------------------ ///----------------------------
/// @name Accessing the Image Downloader /// @name Accessing Image Cache
///------------------------------------ ///----------------------------
/**
The image cache used to improve image loading performance on scroll views. By default, this is an `NSCache` subclass conforming to the `AFImageCache` protocol, which listens for notification warnings and evicts objects accordingly.
*/
+ (id <AFImageCache>)sharedImageCache;
/** /**
Set the shared image downloader used to download images. Set the cache used for image loading.
@param imageDownloader The shared image downloader used to download images. @param imageCache The image cache.
*/ */
+ (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader; + (void)setSharedImageCache:(__nullable id <AFImageCache>)imageCache;
///------------------------------------
/// @name Accessing Response Serializer
///------------------------------------
/** /**
The shared image downloader used to download images. The response serializer used to create an image representation from the server response and response data. By default, this is an instance of `AFImageResponseSerializer`.
@discussion Subclasses of `AFImageResponseSerializer` could be used to perform post-processing, such as color correction, face detection, or other effects. See https://github.com/AFNetworking/AFCoreImageSerializer
*/ */
+ (AFImageDownloader *)sharedImageDownloader; @property (nonatomic, strong) id <AFURLResponseSerialization> imageResponseSerializer;
///-------------------- ///--------------------
/// @name Setting Image /// @name Setting Image
...@@ -89,19 +100,45 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -89,19 +100,45 @@ NS_ASSUME_NONNULL_BEGIN
@param urlRequest The URL request used for the image request. @param urlRequest The URL request used for the image request.
@param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes. @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes.
@param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. @param success A block to be executed when the image request operation finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
@param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. @param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
*/ */
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest - (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
placeholderImage:(nullable UIImage *)placeholderImage placeholderImage:(nullable UIImage *)placeholderImage
success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, UIImage *image))success
failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * __nullable response, NSError *error))failure;
/** /**
Cancels any executing image operation for the receiver, if one exists. Cancels any executing image operation for the receiver, if one exists.
*/ */
- (void)cancelImageDownloadTask; - (void)cancelImageRequestOperation;
@end
#pragma mark -
/**
The `AFImageCache` protocol is adopted by an object used to cache images loaded by the AFNetworking category on `UIImageView`.
*/
@protocol AFImageCache <NSObject>
/**
Returns a cached image for the specified request, if available.
@param request The image request.
@return The cached image.
*/
- (nullable UIImage *)cachedImageForRequest:(NSURLRequest *)request;
/**
Caches a particular image for the specified request.
@param image The image to cache.
@param request The request to be used as a cache key.
*/
- (void)cacheImage:(UIImage *)image
forRequest:(NSURLRequest *)request;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
......
// UIKit+AFNetworking.h // UIKit+AFNetworking.h
// //
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2013 AFNetworking (http://afnetworking.com/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -20,23 +20,20 @@ ...@@ -20,23 +20,20 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#if TARGET_OS_IOS || TARGET_OS_TV #if TARGET_OS_IOS
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#ifndef _UIKIT_AFNETWORKING_ #ifndef _UIKIT_AFNETWORKING_
#define _UIKIT_AFNETWORKING_ #define _UIKIT_AFNETWORKING_
#if TARGET_OS_IOS
#import "AFAutoPurgingImageCache.h"
#import "AFImageDownloader.h"
#import "AFNetworkActivityIndicatorManager.h" #import "AFNetworkActivityIndicatorManager.h"
#import "UIRefreshControl+AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#endif
#import "UIActivityIndicatorView+AFNetworking.h" #import "UIActivityIndicatorView+AFNetworking.h"
#import "UIAlertView+AFNetworking.h"
#import "UIButton+AFNetworking.h" #import "UIButton+AFNetworking.h"
#import "UIImageView+AFNetworking.h" #import "UIImageView+AFNetworking.h"
#import "UIProgressView+AFNetworking.h" #import "UIProgressView+AFNetworking.h"
#import "UIRefreshControl+AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#endif /* _UIKIT_AFNETWORKING_ */ #endif /* _UIKIT_AFNETWORKING_ */
#endif #endif
// UIProgressView+AFNetworking.h // UIProgressView+AFNetworking.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -21,17 +21,18 @@ ...@@ -21,17 +21,18 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TargetConditionals.h> #import <Availability.h>
#if TARGET_OS_IOS || TARGET_OS_TV #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class AFURLConnectionOperation;
/** /**
This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task. This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task or request operation.
*/ */
@interface UIProgressView (AFNetworking) @interface UIProgressView (AFNetworking)
...@@ -45,8 +46,10 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -45,8 +46,10 @@ NS_ASSUME_NONNULL_BEGIN
@param task The session task. @param task The session task.
@param animated `YES` if the change should be animated, `NO` if the change should happen immediately. @param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
*/ */
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task
animated:(BOOL)animated; animated:(BOOL)animated;
#endif
/** /**
Binds the progress to the download progress of the specified session task. Binds the progress to the download progress of the specified session task.
...@@ -54,8 +57,32 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -54,8 +57,32 @@ NS_ASSUME_NONNULL_BEGIN
@param task The session task. @param task The session task.
@param animated `YES` if the change should be animated, `NO` if the change should happen immediately. @param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
*/ */
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task
animated:(BOOL)animated; animated:(BOOL)animated;
#endif
///------------------------------------
/// @name Setting Session Task Progress
///------------------------------------
/**
Binds the progress to the upload progress of the specified request operation.
@param operation The request operation.
@param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
*/
- (void)setProgressWithUploadProgressOfOperation:(AFURLConnectionOperation *)operation
animated:(BOOL)animated;
/**
Binds the progress to the download progress of the specified request operation.
@param operation The request operation.
@param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
*/
- (void)setProgressWithDownloadProgressOfOperation:(AFURLConnectionOperation *)operation
animated:(BOOL)animated;
@end @end
......
// UIProgressView+AFNetworking.m // UIProgressView+AFNetworking.m
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -23,13 +23,33 @@ ...@@ -23,13 +23,33 @@
#import <objc/runtime.h> #import <objc/runtime.h>
#if TARGET_OS_IOS || TARGET_OS_TV #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import "AFURLConnectionOperation.h"
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
#import "AFURLSessionManager.h" #import "AFURLSessionManager.h"
#endif
static void * AFTaskCountOfBytesSentContext = &AFTaskCountOfBytesSentContext; static void * AFTaskCountOfBytesSentContext = &AFTaskCountOfBytesSentContext;
static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedContext; static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedContext;
@interface AFURLConnectionOperation (_UIProgressView)
@property (readwrite, nonatomic, copy) void (^uploadProgress)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected);
@property (readwrite, nonatomic, assign, setter = af_setUploadProgressAnimated:) BOOL af_uploadProgressAnimated;
@property (readwrite, nonatomic, copy) void (^downloadProgress)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected);
@property (readwrite, nonatomic, assign, setter = af_setDownloadProgressAnimated:) BOOL af_downloadProgressAnimated;
@end
@implementation AFURLConnectionOperation (_UIProgressView)
@dynamic uploadProgress; // Implemented in AFURLConnectionOperation
@dynamic af_uploadProgressAnimated;
@dynamic downloadProgress; // Implemented in AFURLConnectionOperation
@dynamic af_downloadProgressAnimated;
@end
#pragma mark - #pragma mark -
@implementation UIProgressView (AFNetworking) @implementation UIProgressView (AFNetworking)
...@@ -52,13 +72,10 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon ...@@ -52,13 +72,10 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon
#pragma mark - #pragma mark -
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task
animated:(BOOL)animated animated:(BOOL)animated
{ {
if (task.state == NSURLSessionTaskStateCompleted) {
return;
}
[task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext]; [task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext];
[task addObserver:self forKeyPath:@"countOfBytesSent" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext]; [task addObserver:self forKeyPath:@"countOfBytesSent" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext];
...@@ -68,15 +85,52 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon ...@@ -68,15 +85,52 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon
- (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task
animated:(BOOL)animated animated:(BOOL)animated
{ {
if (task.state == NSURLSessionTaskStateCompleted) {
return;
}
[task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext]; [task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext];
[task addObserver:self forKeyPath:@"countOfBytesReceived" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext]; [task addObserver:self forKeyPath:@"countOfBytesReceived" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext];
[self af_setDownloadProgressAnimated:animated]; [self af_setDownloadProgressAnimated:animated];
} }
#endif
#pragma mark -
- (void)setProgressWithUploadProgressOfOperation:(AFURLConnectionOperation *)operation
animated:(BOOL)animated
{
__weak __typeof(self)weakSelf = self;
void (^original)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) = [operation.uploadProgress copy];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
if (original) {
original(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
}
dispatch_async(dispatch_get_main_queue(), ^{
if (totalBytesExpectedToWrite > 0) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
[strongSelf setProgress:(totalBytesWritten / (totalBytesExpectedToWrite * 1.0f)) animated:animated];
}
});
}];
}
- (void)setProgressWithDownloadProgressOfOperation:(AFURLConnectionOperation *)operation
animated:(BOOL)animated
{
__weak __typeof(self)weakSelf = self;
void (^original)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) = [operation.downloadProgress copy];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
if (original) {
original(bytesRead, totalBytesRead, totalBytesExpectedToRead);
}
dispatch_async(dispatch_get_main_queue(), ^{
if (totalBytesExpectedToRead > 0) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
[strongSelf setProgress:(totalBytesRead / (totalBytesExpectedToRead * 1.0f)) animated:animated];
}
});
}];
}
#pragma mark - NSKeyValueObserving #pragma mark - NSKeyValueObserving
...@@ -85,6 +139,7 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon ...@@ -85,6 +139,7 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon
change:(__unused NSDictionary *)change change:(__unused NSDictionary *)change
context:(void *)context context:(void *)context
{ {
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
if (context == AFTaskCountOfBytesSentContext || context == AFTaskCountOfBytesReceivedContext) { if (context == AFTaskCountOfBytesSentContext || context == AFTaskCountOfBytesReceivedContext) {
if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesSent))]) { if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesSent))]) {
if ([object countOfBytesExpectedToSend] > 0) { if ([object countOfBytesExpectedToSend] > 0) {
...@@ -119,6 +174,7 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon ...@@ -119,6 +174,7 @@ static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedCon
} }
} }
} }
#endif
} }
@end @end
......
// UIRefreshControl+AFNetworking.m // UIRefreshControl+AFNetworking.m
// //
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2014 AFNetworking (http://afnetworking.com)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -22,16 +22,18 @@ ...@@ -22,16 +22,18 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TargetConditionals.h> #import <Availability.h>
#if TARGET_OS_IOS #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class AFURLConnectionOperation;
/** /**
This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a session task. This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a request operation or session task.
*/ */
@interface UIRefreshControl (AFNetworking) @interface UIRefreshControl (AFNetworking)
...@@ -44,7 +46,20 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -44,7 +46,20 @@ NS_ASSUME_NONNULL_BEGIN
@param task The task. If `nil`, automatic updating from any previously specified operation will be disabled. @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
*/ */
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task; - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
#endif
///----------------------------------------
/// @name Refreshing for Request Operations
///----------------------------------------
/**
Binds the refreshing state to the execution state of the specified operation.
@param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled.
*/
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation;
@end @end
......
// UIRefreshControl+AFNetworking.m // UIRefreshControl+AFNetworking.m
// //
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2014 AFNetworking (http://afnetworking.com)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -23,15 +23,22 @@ ...@@ -23,15 +23,22 @@
#import "UIRefreshControl+AFNetworking.h" #import "UIRefreshControl+AFNetworking.h"
#import <objc/runtime.h> #import <objc/runtime.h>
#if TARGET_OS_IOS #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import "AFHTTPRequestOperation.h"
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
#import "AFURLSessionManager.h" #import "AFURLSessionManager.h"
#endif
@interface AFRefreshControlNotificationObserver : NSObject @interface AFRefreshControlNotificationObserver : NSObject
@property (readonly, nonatomic, weak) UIRefreshControl *refreshControl; @property (readonly, nonatomic, weak) UIRefreshControl *refreshControl;
- (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl; - (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl;
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task; - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
#endif
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation;
@end @end
...@@ -46,9 +53,15 @@ ...@@ -46,9 +53,15 @@
return notificationObserver; return notificationObserver;
} }
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task { - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
[[self af_notificationObserver] setRefreshingWithStateOfTask:task]; [[self af_notificationObserver] setRefreshingWithStateOfTask:task];
} }
#endif
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation {
[[self af_notificationObserver] setRefreshingWithStateOfOperation:operation];
}
@end @end
...@@ -63,6 +76,7 @@ ...@@ -63,6 +76,7 @@
return self; return self;
} }
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task { - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
...@@ -71,16 +85,44 @@ ...@@ -71,16 +85,44 @@
[notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
if (task) { if (task) {
UIRefreshControl *refreshControl = self.refreshControl; #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
if (task.state == NSURLSessionTaskStateRunning) { if (task.state == NSURLSessionTaskStateRunning) {
[refreshControl beginRefreshing]; [self.refreshControl beginRefreshing];
[notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task];
[notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task];
[notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task];
} else { } else {
[refreshControl endRefreshing]; [self.refreshControl endRefreshing];
} }
#pragma clang diagnostic pop
}
}
#endif
- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
if (operation) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
if (![operation isFinished]) {
if ([operation isExecuting]) {
[self.refreshControl beginRefreshing];
} else {
[self.refreshControl endRefreshing];
}
[notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingOperationDidStartNotification object:operation];
[notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingOperationDidFinishNotification object:operation];
}
#pragma clang diagnostic pop
} }
} }
...@@ -88,13 +130,19 @@ ...@@ -88,13 +130,19 @@
- (void)af_beginRefreshing { - (void)af_beginRefreshing {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
[self.refreshControl beginRefreshing]; [self.refreshControl beginRefreshing];
#pragma clang diagnostic pop
}); });
} }
- (void)af_endRefreshing { - (void)af_endRefreshing {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreceiver-is-weak"
[self.refreshControl endRefreshing]; [self.refreshControl endRefreshing];
#pragma clang diagnostic pop
}); });
} }
...@@ -103,9 +151,14 @@ ...@@ -103,9 +151,14 @@
- (void)dealloc { - (void)dealloc {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
[notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
#endif
[notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil];
[notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil];
} }
@end @end
......
// UIWebView+AFNetworking.h // UIWebView+AFNetworking.h
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -21,15 +21,16 @@ ...@@ -21,15 +21,16 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TargetConditionals.h> #import <Availability.h>
#if TARGET_OS_IOS #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class AFHTTPSessionManager; @class AFHTTPRequestSerializer, AFHTTPResponseSerializer;
@protocol AFURLRequestSerialization, AFURLResponseSerialization;
/** /**
This category adds methods to the UIKit framework's `UIWebView` class. The methods in this category provide increased control over the request cycle, including progress monitoring and success / failure handling. This category adds methods to the UIKit framework's `UIWebView` class. The methods in this category provide increased control over the request cycle, including progress monitoring and success / failure handling.
...@@ -39,20 +40,25 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -39,20 +40,25 @@ NS_ASSUME_NONNULL_BEGIN
@interface UIWebView (AFNetworking) @interface UIWebView (AFNetworking)
/** /**
The session manager used to download all requests. The request serializer used to serialize requests made with the `-loadRequest:...` category methods. By default, this is an instance of `AFHTTPRequestSerializer`.
*/ */
@property (nonatomic, strong) AFHTTPSessionManager *sessionManager; @property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer;
/**
The response serializer used to serialize responses made with the `-loadRequest:...` category methods. By default, this is an instance of `AFHTTPResponseSerializer`.
*/
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;
/** /**
Asynchronously loads the specified request. Asynchronously loads the specified request.
@param request A URL request identifying the location of the content to load. This must not be `nil`. @param request A URL request identifying the location of the content to load. This must not be `nil`.
@param progress A progress object monitoring the current download progress. @param progress 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.
@param success A block object to be executed when the request finishes loading successfully. This block returns the HTML string to be loaded by the web view, and takes two arguments: the response, and the response string. @param success A block object to be executed when the request finishes loading successfully. This block returns the HTML string to be loaded by the web view, and takes two arguments: the response, and the response string.
@param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred.
*/ */
- (void)loadRequest:(NSURLRequest *)request - (void)loadRequest:(NSURLRequest *)request
progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress progress:(nullable void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
success:(nullable NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success success:(nullable NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success
failure:(nullable void (^)(NSError *error))failure; failure:(nullable void (^)(NSError *error))failure;
...@@ -62,14 +68,14 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -62,14 +68,14 @@ NS_ASSUME_NONNULL_BEGIN
@param request A URL request identifying the location of the content to load. This must not be `nil`. @param request A URL request identifying the location of the content to load. This must not be `nil`.
@param MIMEType The MIME type of the content. Defaults to the content type of the response if not specified. @param MIMEType The MIME type of the content. Defaults to the content type of the response if not specified.
@param textEncodingName The IANA encoding name, as in `utf-8` or `utf-16`. Defaults to the response text encoding if not specified. @param textEncodingName The IANA encoding name, as in `utf-8` or `utf-16`. Defaults to the response text encoding if not specified.
@param progress A progress object monitoring the current download progress. @param progress 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.
@param success A block object to be executed when the request finishes loading successfully. This block returns the data to be loaded by the web view and takes two arguments: the response, and the downloaded data. @param success A block object to be executed when the request finishes loading successfully. This block returns the data to be loaded by the web view and takes two arguments: the response, and the downloaded data.
@param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred. @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred.
*/ */
- (void)loadRequest:(NSURLRequest *)request - (void)loadRequest:(NSURLRequest *)request
MIMEType:(nullable NSString *)MIMEType MIMEType:(nullable NSString *)MIMEType
textEncodingName:(nullable NSString *)textEncodingName textEncodingName:(nullable NSString *)textEncodingName
progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress progress:(nullable void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
success:(nullable NSData * (^)(NSHTTPURLResponse *response, NSData *data))success success:(nullable NSData * (^)(NSHTTPURLResponse *response, NSData *data))success
failure:(nullable void (^)(NSError *error))failure; failure:(nullable void (^)(NSError *error))failure;
......
// UIWebView+AFNetworking.m // UIWebView+AFNetworking.m
// Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
...@@ -23,24 +23,24 @@ ...@@ -23,24 +23,24 @@
#import <objc/runtime.h> #import <objc/runtime.h>
#if TARGET_OS_IOS #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
#import "AFHTTPSessionManager.h" #import "AFHTTPRequestOperation.h"
#import "AFURLResponseSerialization.h" #import "AFURLResponseSerialization.h"
#import "AFURLRequestSerialization.h" #import "AFURLRequestSerialization.h"
@interface UIWebView (_AFNetworking) @interface UIWebView (_AFNetworking)
@property (readwrite, nonatomic, strong, setter = af_setURLSessionTask:) NSURLSessionDataTask *af_URLSessionTask; @property (readwrite, nonatomic, strong, setter = af_setHTTPRequestOperation:) AFHTTPRequestOperation *af_HTTPRequestOperation;
@end @end
@implementation UIWebView (_AFNetworking) @implementation UIWebView (_AFNetworking)
- (NSURLSessionDataTask *)af_URLSessionTask { - (AFHTTPRequestOperation *)af_HTTPRequestOperation {
return (NSURLSessionDataTask *)objc_getAssociatedObject(self, @selector(af_URLSessionTask)); return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, @selector(af_HTTPRequestOperation));
} }
- (void)af_setURLSessionTask:(NSURLSessionDataTask *)af_URLSessionTask { - (void)af_setHTTPRequestOperation:(AFHTTPRequestOperation *)operation {
objc_setAssociatedObject(self, @selector(af_URLSessionTask), af_URLSessionTask, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(self, @selector(af_HTTPRequestOperation), operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
} }
@end @end
...@@ -49,20 +49,21 @@ ...@@ -49,20 +49,21 @@
@implementation UIWebView (AFNetworking) @implementation UIWebView (AFNetworking)
- (AFHTTPSessionManager *)sessionManager { - (AFHTTPRequestSerializer <AFURLRequestSerialization> *)requestSerializer {
static AFHTTPSessionManager *_af_defaultHTTPSessionManager = nil; static AFHTTPRequestSerializer <AFURLRequestSerialization> *_af_defaultRequestSerializer = nil;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
_af_defaultHTTPSessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; _af_defaultRequestSerializer = [AFHTTPRequestSerializer serializer];
_af_defaultHTTPSessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
_af_defaultHTTPSessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
}); });
return objc_getAssociatedObject(self, @selector(sessionManager)) ?: _af_defaultHTTPSessionManager; #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
return objc_getAssociatedObject(self, @selector(requestSerializer)) ?: _af_defaultRequestSerializer;
#pragma clang diagnostic pop
} }
- (void)setSessionManager:(AFHTTPSessionManager *)sessionManager { - (void)setRequestSerializer:(AFHTTPRequestSerializer<AFURLRequestSerialization> *)requestSerializer {
objc_setAssociatedObject(self, @selector(sessionManager), sessionManager, OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(self, @selector(requestSerializer), requestSerializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
} }
- (AFHTTPResponseSerializer <AFURLResponseSerialization> *)responseSerializer { - (AFHTTPResponseSerializer <AFURLResponseSerialization> *)responseSerializer {
...@@ -72,7 +73,10 @@ ...@@ -72,7 +73,10 @@
_af_defaultResponseSerializer = [AFHTTPResponseSerializer serializer]; _af_defaultResponseSerializer = [AFHTTPResponseSerializer serializer];
}); });
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
return objc_getAssociatedObject(self, @selector(responseSerializer)) ?: _af_defaultResponseSerializer; return objc_getAssociatedObject(self, @selector(responseSerializer)) ?: _af_defaultResponseSerializer;
#pragma clang diagnostic pop
} }
- (void)setResponseSerializer:(AFHTTPResponseSerializer<AFURLResponseSerialization> *)responseSerializer { - (void)setResponseSerializer:(AFHTTPResponseSerializer<AFURLResponseSerialization> *)responseSerializer {
...@@ -82,7 +86,7 @@ ...@@ -82,7 +86,7 @@
#pragma mark - #pragma mark -
- (void)loadRequest:(NSURLRequest *)request - (void)loadRequest:(NSURLRequest *)request
progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress progress:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
success:(NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success success:(NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success
failure:(void (^)(NSError *error))failure failure:(void (^)(NSError *error))failure
{ {
...@@ -107,45 +111,43 @@ ...@@ -107,45 +111,43 @@
- (void)loadRequest:(NSURLRequest *)request - (void)loadRequest:(NSURLRequest *)request
MIMEType:(NSString *)MIMEType MIMEType:(NSString *)MIMEType
textEncodingName:(NSString *)textEncodingName textEncodingName:(NSString *)textEncodingName
progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress progress:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress
success:(NSData * (^)(NSHTTPURLResponse *response, NSData *data))success success:(NSData * (^)(NSHTTPURLResponse *response, NSData *data))success
failure:(void (^)(NSError *error))failure failure:(void (^)(NSError *error))failure
{ {
NSParameterAssert(request); NSParameterAssert(request);
if (self.af_URLSessionTask.state == NSURLSessionTaskStateRunning || self.af_URLSessionTask.state == NSURLSessionTaskStateSuspended) { if (self.af_HTTPRequestOperation) {
[self.af_URLSessionTask cancel]; [self.af_HTTPRequestOperation cancel];
} }
self.af_URLSessionTask = nil;
request = [self.requestSerializer requestBySerializingRequest:request withParameters:nil error:nil];
self.af_HTTPRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
self.af_HTTPRequestOperation.responseSerializer = self.responseSerializer;
__weak __typeof(self)weakSelf = self; __weak __typeof(self)weakSelf = self;
__block NSURLSessionDataTask *dataTask; [self.af_HTTPRequestOperation setDownloadProgressBlock:progress];
dataTask = [self.sessionManager [self.af_HTTPRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id __unused responseObject) {
dataTaskWithRequest:request NSData *data = success ? success(operation.response, operation.responseData) : operation.responseData;
uploadProgress:nil
downloadProgress:nil #pragma clang diagnostic push
completionHandler:^(NSURLResponse * _Nonnull response, id _Nonnull responseObject, NSError * _Nullable error) { #pragma clang diagnostic ignored "-Wgnu"
__strong __typeof(weakSelf) strongSelf = weakSelf; __strong __typeof(weakSelf) strongSelf = weakSelf;
if (error) { [strongSelf loadData:data MIMEType:(MIMEType ?: [operation.response MIMEType]) textEncodingName:(textEncodingName ?: [operation.response textEncodingName]) baseURL:[operation.response URL]];
if (failure) {
failure(error); if ([strongSelf.delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) {
} [strongSelf.delegate webViewDidFinishLoad:strongSelf];
} else { }
if (success) {
success((NSHTTPURLResponse *)response, responseObject); #pragma clang diagnostic pop
} } failure:^(AFHTTPRequestOperation * __unused operation, NSError *error) {
[strongSelf loadData:responseObject MIMEType:MIMEType textEncodingName:textEncodingName baseURL:[dataTask.currentRequest URL]]; if (failure) {
failure(error);
if ([strongSelf.delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { }
[strongSelf.delegate webViewDidFinishLoad:strongSelf]; }];
}
} [self.af_HTTPRequestOperation start];
}];
self.af_URLSessionTask = dataTask;
if (progress != nil) {
*progress = [self.sessionManager downloadProgressForTask:dataTask];
}
[self.af_URLSessionTask resume];
if ([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) { if ([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) {
[self.delegate webViewDidStartLoad:self]; [self.delegate webViewDidStartLoad:self];
......
PODS: PODS:
- AFNetworking (3.2.1): - AFJSONRPCClient (2.1.1):
- AFNetworking/NSURLSession (= 3.2.1) - AFNetworking (~> 2.1)
- AFNetworking/Reachability (= 3.2.1) - AFNetworking (2.7.0):
- AFNetworking/Security (= 3.2.1) - AFNetworking/NSURLConnection (= 2.7.0)
- AFNetworking/Serialization (= 3.2.1) - AFNetworking/NSURLSession (= 2.7.0)
- AFNetworking/UIKit (= 3.2.1) - AFNetworking/Reachability (= 2.7.0)
- AFNetworking/NSURLSession (3.2.1): - AFNetworking/Security (= 2.7.0)
- AFNetworking/Serialization (= 2.7.0)
- AFNetworking/UIKit (= 2.7.0)
- AFNetworking/NSURLConnection (2.7.0):
- AFNetworking/Reachability - AFNetworking/Reachability
- AFNetworking/Security - AFNetworking/Security
- AFNetworking/Serialization - AFNetworking/Serialization
- AFNetworking/Reachability (3.2.1) - AFNetworking/NSURLSession (2.7.0):
- AFNetworking/Security (3.2.1) - AFNetworking/Reachability
- AFNetworking/Serialization (3.2.1) - AFNetworking/Security
- AFNetworking/UIKit (3.2.1): - AFNetworking/Serialization
- AFNetworking/Reachability (2.7.0)
- AFNetworking/Security (2.7.0)
- AFNetworking/Serialization (2.7.0)
- AFNetworking/UIKit (2.7.0):
- AFNetworking/NSURLConnection
- AFNetworking/NSURLSession - AFNetworking/NSURLSession
- IQKeyboardManager (6.5.6) - IQKeyboardManager (6.5.6)
- Masonry (1.1.0) - Masonry (1.1.0)
DEPENDENCIES: DEPENDENCIES:
- AFJSONRPCClient
- AFNetworking - AFNetworking
- IQKeyboardManager - IQKeyboardManager
- Masonry - Masonry
SPEC REPOS: SPEC REPOS:
https://github.com/CocoaPods/Specs.git: https://github.com/CocoaPods/Specs.git:
- AFJSONRPCClient
- AFNetworking - AFNetworking
- IQKeyboardManager - IQKeyboardManager
- Masonry - Masonry
SPEC CHECKSUMS: SPEC CHECKSUMS:
AFNetworking: b6f891fdfaed196b46c7a83cf209e09697b94057 AFJSONRPCClient: 333bada91e6e45398446b8bd84e238e6f2389b1b
AFNetworking: 8dd5f9b9691e09186393069a12cc3b5ed7c8b511
IQKeyboardManager: 2a6e97afdafc7becf0cb17a9a8d795e3a980717f IQKeyboardManager: 2a6e97afdafc7becf0cb17a9a8d795e3a980717f
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
PODFILE CHECKSUM: 05dc85bcfeedc8253c411e67a7ee98c5ff6bdd07 PODFILE CHECKSUM: c17dd2b51db38ebc1361046f88ac3934293eb4ef
COCOAPODS: 1.8.3 COCOAPODS: 1.8.3
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForAnalyzing = "YES"
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3A7F4502B2215DA26D792623E9552CCD"
BuildableName = "AFJSONRPCClient.framework"
BlueprintName = "AFJSONRPCClient"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
buildConfiguration = "Debug"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
<dict> <dict>
<key>SchemeUserState</key> <key>SchemeUserState</key>
<dict> <dict>
<key>AFJSONRPCClient.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
</dict>
<key>AFNetworking.xcscheme</key> <key>AFNetworking.xcscheme</key>
<dict> <dict>
<key>isShown</key> <key>isShown</key>
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.1.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
#import <Foundation/Foundation.h>
@interface PodsDummy_AFJSONRPCClient : NSObject
@end
@implementation PodsDummy_AFJSONRPCClient
@end
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#import "AFJSONRPCClient.h"
FOUNDATION_EXPORT double AFJSONRPCClientVersionNumber;
FOUNDATION_EXPORT const unsigned char AFJSONRPCClientVersionString[];
framework module AFJSONRPCClient {
umbrella header "AFJSONRPCClient-umbrella.h"
export *
module * { export * }
}
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/AFJSONRPCClient
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/AFJSONRPCClient
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>3.2.1</string> <string>2.7.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
......
...@@ -17,7 +17,3 @@ ...@@ -17,7 +17,3 @@
#ifndef TARGET_OS_WATCH #ifndef TARGET_OS_WATCH
#define TARGET_OS_WATCH 0 #define TARGET_OS_WATCH 0
#endif #endif
#ifndef TARGET_OS_TV
#define TARGET_OS_TV 0
#endif
...@@ -11,17 +11,18 @@ ...@@ -11,17 +11,18 @@
#endif #endif
#import "AFNetworking.h" #import "AFNetworking.h"
#import "AFURLConnectionOperation.h"
#import "AFHTTPRequestOperation.h"
#import "AFHTTPRequestOperationManager.h"
#import "AFHTTPSessionManager.h" #import "AFHTTPSessionManager.h"
#import "AFURLSessionManager.h" #import "AFURLSessionManager.h"
#import "AFCompatibilityMacros.h"
#import "AFNetworkReachabilityManager.h" #import "AFNetworkReachabilityManager.h"
#import "AFSecurityPolicy.h" #import "AFSecurityPolicy.h"
#import "AFURLRequestSerialization.h" #import "AFURLRequestSerialization.h"
#import "AFURLResponseSerialization.h" #import "AFURLResponseSerialization.h"
#import "AFAutoPurgingImageCache.h"
#import "AFImageDownloader.h"
#import "AFNetworkActivityIndicatorManager.h" #import "AFNetworkActivityIndicatorManager.h"
#import "UIActivityIndicatorView+AFNetworking.h" #import "UIActivityIndicatorView+AFNetworking.h"
#import "UIAlertView+AFNetworking.h"
#import "UIButton+AFNetworking.h" #import "UIButton+AFNetworking.h"
#import "UIImage+AFNetworking.h" #import "UIImage+AFNetworking.h"
#import "UIImageView+AFNetworking.h" #import "UIImageView+AFNetworking.h"
......
# Acknowledgements # Acknowledgements
This application makes use of the following third party libraries: This application makes use of the following third party libraries:
## AFJSONRPCClient
Copyright (c) 2013 JustCommunication
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## AFNetworking ## AFNetworking
Copyright (c) 2011-2016 Alamofire Software Foundation (http://alamofire.org/) Copyright (c) 2011–2015 Alamofire Software Foundation (http://alamofire.org/)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
...@@ -14,7 +14,36 @@ ...@@ -14,7 +14,36 @@
</dict> </dict>
<dict> <dict>
<key>FooterText</key> <key>FooterText</key>
<string>Copyright (c) 2011-2016 Alamofire Software Foundation (http://alamofire.org/) <string>Copyright (c) 2013 JustCommunication
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>AFJSONRPCClient</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 20112015 Alamofire Software Foundation (http://alamofire.org/)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
......
${PODS_ROOT}/Target Support Files/Pods-MutiFaceDemo/Pods-MutiFaceDemo-frameworks.sh ${PODS_ROOT}/Target Support Files/Pods-MutiFaceDemo/Pods-MutiFaceDemo-frameworks.sh
${BUILT_PRODUCTS_DIR}/AFJSONRPCClient/AFJSONRPCClient.framework
${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework ${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework ${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework ${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework
\ No newline at end of file
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFJSONRPCClient.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework
\ No newline at end of file
${PODS_ROOT}/Target Support Files/Pods-MutiFaceDemo/Pods-MutiFaceDemo-frameworks.sh ${PODS_ROOT}/Target Support Files/Pods-MutiFaceDemo/Pods-MutiFaceDemo-frameworks.sh
${BUILT_PRODUCTS_DIR}/AFJSONRPCClient/AFJSONRPCClient.framework
${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework ${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework
${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework ${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework
${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework ${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework
\ No newline at end of file
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFJSONRPCClient.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManager.framework
${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework
\ No newline at end of file
...@@ -161,11 +161,13 @@ strip_invalid_archs() { ...@@ -161,11 +161,13 @@ strip_invalid_archs() {
if [[ "$CONFIGURATION" == "Debug" ]]; then if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/AFJSONRPCClient/AFJSONRPCClient.framework"
install_framework "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework" install_framework "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework"
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework" install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework" install_framework "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework"
fi fi
if [[ "$CONFIGURATION" == "Release" ]]; then if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/AFJSONRPCClient/AFJSONRPCClient.framework"
install_framework "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework" install_framework "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework"
install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework" install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManager/IQKeyboardManager.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework" install_framework "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework"
......
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFJSONRPCClient" "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFJSONRPCClient/AFJSONRPCClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "AFNetworking" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManager" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" OTHER_LDFLAGS = $(inherited) -framework "AFJSONRPCClient" -framework "AFNetworking" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManager" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit"
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
......
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFJSONRPCClient" "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFJSONRPCClient/AFJSONRPCClient.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManager/IQKeyboardManager.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "AFNetworking" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManager" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" OTHER_LDFLAGS = $(inherited) -framework "AFJSONRPCClient" -framework "AFNetworking" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManager" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit"
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册登录 后发表评论