From acad6146704e660db98cfb55341652901c88f856 Mon Sep 17 00:00:00 2001 From: OYXJ Date: Wed, 16 Nov 2016 23:58:56 +0800 Subject: [PATCH 1/2] =?UTF-8?q?AFHTTPRequestOperation=20=E2=80=94>=20NSURL?= =?UTF-8?q?SessionDataTask?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit modify by OYXJ on 2016.08 AFHTTPRequestOperation —> NSURLSessionDataTask XML formart via Ono --- AFWebDAVManager/AFWebDAVManager.h | 204 +++- AFWebDAVManager/AFWebDAVManager.m | 1549 +++++++++++++++++++++++++++-- AFWebDAVManager/README.md | 49 + 3 files changed, 1726 insertions(+), 76 deletions(-) mode change 100644 => 100755 AFWebDAVManager/AFWebDAVManager.h mode change 100644 => 100755 AFWebDAVManager/AFWebDAVManager.m create mode 100755 AFWebDAVManager/README.md diff --git a/AFWebDAVManager/AFWebDAVManager.h b/AFWebDAVManager/AFWebDAVManager.h old mode 100644 new mode 100755 index 780d909..e8ebb84 --- a/AFWebDAVManager/AFWebDAVManager.h +++ b/AFWebDAVManager/AFWebDAVManager.h @@ -22,7 +22,10 @@ #import -#import "AFHTTPRequestOperationManager.h" +//#import "AFHTTPRequestOperationManager.h" +#import //add by OYXJ on 2016.08.08 +#import "ONOXMLDocument.h"//add by OYXJ on 2016.09.21 + typedef NS_ENUM(NSUInteger, AFWebDAVDepth) { AFWebDAVZeroDepth = 0, @@ -46,7 +49,8 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @see http://tools.ietf.org/html/rfc4918 */ -@interface AFWebDAVManager : AFHTTPRequestOperationManager +//@interface AFWebDAVManager : AFHTTPRequestOperationManager +@interface AFWebDAVManager : AFHTTPSessionManager//add by OYXJ on 2016.08.08 ///------------------------------- /// @name Accessing XML Namespaces @@ -57,6 +61,12 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { */ @property (nonatomic, strong) NSDictionary *namespacesKeyedByAbbreviation; +/** + XML the default abbreviation of namespaces. default is "D" + */ +@property (nonatomic, strong) NSString *defaultAbbreviationOfXMLnamespaces; + + ///------------------------------- /// @name File Manager Interaction ///------------------------------- @@ -86,9 +96,15 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { /** Removes a file at the path represented by the specified URL string. + modify by OYXJ on 2016.08 */ -- (void)removeFileAtURLString:(NSString *)URLString - completionHandler:(void (^)(NSURL *fileURL, NSError *error))completionHandler; +- (NSURLSessionDataTask *)removeFileAtURLString:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + extraHeaderDic:(NSDictionary *)extraHeaderDic //request的HTTPHeaderField + dataType:(NSString *)dataType //数据类型 + attributesData:(NSDictionary *)attributesDataToDelete //数据项 + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; /** Moves a file from path to another path represented by the specified URL strings. @@ -127,11 +143,26 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @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. @see -HTTPRequestOperationWithRequest:success:failure: + + modify by OYXJ on 2016.08 */ +- (NSURLSessionDataTask *)multiPUT:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + extraHeaderDic:(NSDictionary *)extraHeaderDic //request的HTTPHeaderField + dataType:(NSString *)dataType //数据类型 + attributesData:(NSDictionary *)attributesDataToPut //数据项 + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)PUT:(NSString *)URLString data:(NSData *)data success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; +*/ + + /** Creates and runs an `AFHTTPRequestOperation` with a `PUT` request with contents of the specified file. @@ -142,11 +173,25 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @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. @see -HTTPRequestOperationWithRequest:success:failure: + + modify by OYXJ on 2016.08 */ +- (NSURLSessionDataTask *)multiPUT:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + extraHeaderDic:(NSDictionary *)extraHeaderDic //request的HTTPHeaderField + dataType:(NSString *)dataType //数据类型 + file:(NSURL *)fileURL + attributesData:(NSDictionary *)attributesDataToPut //数据项 + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)PUT:(NSString *)URLString file:(NSURL *)fileURL success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + */ /** Creates and runs an `AFHTTPRequestOperation` with a `PROPFIND` request with the specified properties. @@ -157,12 +202,66 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @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. @see -HTTPRequestOperationWithRequest:success:failure: + + modify by OYXJ on 2016.08 */ +- (NSURLSessionDataTask *)PROPFIND:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + propertyNames:(NSArray *)propertyNames //要获取的数据项 + depth:(AFWebDAVDepth)depth + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)PROPFIND:(NSString *)URLString propertyNames:(NSArray *)propertyNames depth:(AFWebDAVDepth)depth success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; +*/ + + + +/** + GET + + @param URLString <#URLString description#> + @param tokenDic <#tokenDic description#> + + @return <#return value description#> + + add by OYXJ on 2016.10 + */ +- (NSURLSessionDataTask *)GET:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{@"token", tokenStr} + dataType:(NSString *)dataType //数据类型 + pathList:(NSArray *)pathsToGet //数据路径 + depth:(AFWebDAVDepth)depth + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + + +/** + * 获取完整的数据 + * + * @param URLString 服务器地址 + * @param tokenDic 用户token + * + * @return NSURLSessionDataTask* + + modify by OYXJ on 2016.08 + */ +- (NSURLSessionDataTask *)REPORT:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + dataType:(NSString *)dataType //数据类型 + propertyNames:(NSArray *)propertiesToGet //要获取的数据项 + pathList:(NSArray *)pathsToGet //数据路径 + depth:(AFWebDAVDepth)depth + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + + /** Creates and runs an `AFHTTPRequestOperation` with a `PROPPATCH` request with the specified properties to set and remove. @@ -175,11 +274,20 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @see -HTTPRequestOperationWithRequest:success:failure: */ +- (NSURLSessionDataTask *)PROPPATCH:(NSString *)URLString + set:(NSDictionary *)propertiesToSet + remove:(NSArray *)propertiesToRemove + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)PROPPATCH:(NSString *)URLString set:(NSDictionary *)propertiesToSet remove:(NSArray *)propertiesToRemove success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + */ /** Creates and runs an `AFHTTPRequestOperation` with a `MKCOL` request with the specified URL string. @@ -190,9 +298,16 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @see -HTTPRequestOperationWithRequest:success:failure: */ +- (NSURLSessionDataTask *)MKCOL:(NSString *)URLString + success:(void (^)(NSURLSessionDataTask *task, NSURLResponse *response))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)MKCOL:(NSString *)URLString success:(void (^)(AFHTTPRequestOperation *operation, NSURLResponse *response))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + */ /** Creates and runs an `AFHTTPRequestOperation` with a `COPY` request with the specified source and destination URL strings. @@ -206,12 +321,22 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @see -HTTPRequestOperationWithRequest:success:failure: */ +- (NSURLSessionDataTask *)COPY:(NSString *)sourceURLString + destination:(NSString *)destinationURLString + overwrite:(BOOL)overwrite + conditions:(NSString *)IfHeaderFieldValue + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)COPY:(NSString *)sourceURLString destination:(NSString *)destinationURLString overwrite:(BOOL)overwrite conditions:(NSString *)IfHeaderFieldValue success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + */ /** Creates and runs an `AFHTTPRequestOperation` with a `MOVE` request with the specified source and destination URL strings. @@ -225,12 +350,22 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @see -HTTPRequestOperationWithRequest:success:failure: */ +- (NSURLSessionDataTask *)MOVE:(NSString *)sourceURLString + destination:(NSString *)destinationURLString + overwrite:(BOOL)overwrite + conditions:(NSString *)IfHeaderFieldValue + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)MOVE:(NSString *)sourceURLString destination:(NSString *)destinationURLString overwrite:(BOOL)overwrite conditions:(NSString *)IfHeaderFieldValue success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + */ /** Creates and runs an `AFHTTPRequestOperation` with a `LOCK` request with the specified URL string and lock attributes. @@ -246,6 +381,17 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @see -HTTPRequestOperationWithRequest:success:failure: */ +- (NSURLSessionDataTask *)LOCK:(NSString *)URLString + timeout:(NSTimeInterval)timeoutInterval + depth:(AFWebDAVDepth)depth + scope:(AFWebDAVLockScope)scope + type:(AFWebDAVLockType)type + owner:(NSURL *)ownerURL + success:(void (^)(NSURLSessionDataTask *task, NSString *lockToken))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* +replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)LOCK:(NSString *)URLString timeout:(NSTimeInterval)timeoutInterval depth:(AFWebDAVDepth)depth @@ -254,6 +400,7 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { owner:(NSURL *)ownerURL success:(void (^)(AFHTTPRequestOperation *operation, NSString *lockToken))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + */ /** Creates and runs an `AFHTTPRequestOperation` with a `UNLOCK` request with the specified URL string and lock attributes. @@ -265,10 +412,18 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @see -HTTPRequestOperationWithRequest:success:failure: */ +- (NSURLSessionDataTask *)UNLOCK:(NSString *)URLString + token:(NSString *)lockToken + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)UNLOCK:(NSString *)URLString token:(NSString *)lockToken success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + */ @end @@ -299,10 +454,48 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { @end + + + +/*! @brief Describes a resource on a remote server. This could be a directory or an actual file. + * @author OuYangXiaoJin 2016.09.22 + */ +@protocol WebDavResource + +/** + The `etag` of the resource at the response URL. + */ +@property (readonly, nonatomic, copy) NSString *etag; + +/** + 服务端资源的唯一id(主键) + 相当于 source id + */ +@property(nonatomic, copy, readonly) NSString *name; // 相当于 source id + +//@property(nonatomic, copy, readonly) NSString *ctag; + +@property(nonatomic, strong, readonly)NSDictionary *customProps; + +//private final Resourcetype resourceType; ??? +//private final String contentType; ??? TODO:: +//private final Long contentLength; ??? TODO:: + +@property(nonatomic, copy, readonly) NSString *notedata; +@property(nonatomic, copy, readonly) NSString *lastModified; +@property(nonatomic, copy, readonly) NSString *deletedTime; +@property(nonatomic, copy, readonly) NSString *deletedDataName; +@property(nonatomic, copy, readonly) NSString *deleted; + +@end + + + + /** `AFWebDavMultiStatusResponse` is a subclass of `NSHTTPURLResponse` that is returned from multi-status responses sent by WebDAV servers. */ -@interface AFWebDAVMultiStatusResponse : NSHTTPURLResponse +@interface AFWebDAVMultiStatusResponse : NSHTTPURLResponse //WebDavResource add by OYXJ on 2016.09.22 ///------------------------------------------- /// @name Getting Response Property Attributes @@ -328,4 +521,5 @@ typedef NS_ENUM(NSUInteger, AFWebDAVLockScope) { */ @property (readonly, nonatomic, copy) NSDate *lastModifiedDate; + @end diff --git a/AFWebDAVManager/AFWebDAVManager.m b/AFWebDAVManager/AFWebDAVManager.m old mode 100644 new mode 100755 index 060ea96..65a62e2 --- a/AFWebDAVManager/AFWebDAVManager.m +++ b/AFWebDAVManager/AFWebDAVManager.m @@ -72,6 +72,7 @@ - (instancetype)initWithBaseURL:(NSURL *)url { } self.namespacesKeyedByAbbreviation = @{@"D": @"DAV:"}; + self.defaultAbbreviationOfXMLnamespaces = @"D"; self.requestSerializer = [AFWebDAVRequestSerializer serializer]; self.responseSerializer = [AFCompoundResponseSerializer compoundSerializerWithResponseSerializers:@[[AFWebDAVMultiStatusResponseSerializer serializer], [AFHTTPResponseSerializer serializer]]]; @@ -81,17 +82,41 @@ - (instancetype)initWithBaseURL:(NSURL *)url { return self; } + +#pragma mark - setters + +- (void)setNamespacesKeyedByAbbreviation:(NSDictionary *)namespacesKeyedByAbbreviation +{ + _namespacesKeyedByAbbreviation = namespacesKeyedByAbbreviation; +} + +- (void)setDefaultAbbreviationOfXMLnamespaces:(NSString *)defaultAbbreviationOfXMLnamespaces +{ + _defaultAbbreviationOfXMLnamespaces = defaultAbbreviationOfXMLnamespaces; +} + + + #pragma mark - - (void)contentsOfDirectoryAtURLString:(NSString *)URLString recursive:(BOOL)recursive completionHandler:(void (^)(NSArray *items, NSError *error))completionHandler { - [self PROPFIND:URLString propertyNames:nil depth:(recursive ? AFWebDAVInfinityDepth : AFWebDAVOneDepth) success:^(__unused AFHTTPRequestOperation *operation, id responseObject) { + [self PROPFIND:URLString tokenDic:nil + propertyNames:nil depth:(recursive ? AFWebDAVInfinityDepth : AFWebDAVOneDepth) success:^(__unused + //AFHTTPRequestOperation *operation, id responseObject) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + NSURLSessionDataTask *task, id responseObject) { + if (completionHandler) { completionHandler(responseObject, nil); } - } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + + //} failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + } failure:^(__unused NSURLSessionDataTask *task, NSError *error) { + if (completionHandler) { completionHandler(nil, error); } @@ -103,24 +128,61 @@ - (void)createDirectoryAtURLString:(NSString *)URLString completionHandler:(void (^)(NSURL *directoryURL, NSError *error))completionHandler { __weak __typeof(self) weakself = self; - [self MKCOL:URLString success:^(__unused AFHTTPRequestOperation *operation, NSURLResponse *response) { + //[self MKCOL:URLString success:^(__unused AFHTTPRequestOperation *operation, NSURLResponse *response) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + [self MKCOL:URLString success:^(__unused NSURLSessionDataTask *task, NSURLResponse *response) { + + if (completionHandler) { + /** + Fixed crash related to sending 'URL' selector to '_NSInlineData' inst… + Ref.: https://github.com/danielr/AFWebDAVManager/commit/1ba182bbbb743465830b694c4120456efc908ac6 + danielr committed on 13 Jan + 1 parent a25f308 commit 1ba182bbbb743465830b694c4120456efc908ac6 + if ([NSStringFromClass([response class]) isEqualToString:@"_NSZeroData"]) { completionHandler(nil, nil); } else { completionHandler([response URL], nil); } + */ + if ([response respondsToSelector:@selector(URL)]) { + completionHandler([response URL], nil); + } else { + completionHandler(nil, nil); + } } - } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + //} failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + } failure:^(__unused NSURLSessionDataTask *task, NSError *error) { + __strong __typeof(weakself) strongSelf = weakself; - if ([operation.response statusCode] == 409 && createIntermediateDirectories) { - NSArray *pathComponents = [[operation.request URL] pathComponents]; + + NSInteger statusCode = 0; + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)(task.response); + if ([httpResponse isKindOfClass:[NSHTTPURLResponse class]]) { + statusCode = httpResponse.statusCode; + } + + //if ([operation.response statusCode] == 409 && createIntermediateDirectories) { + if (statusCode == 409 && createIntermediateDirectories) { + + //NSArray *pathComponents = [[operation.request URL] pathComponents]; + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + NSArray *pathComponents = [[task.originalRequest URL] pathComponents]; + if ([pathComponents count] > 1) { [pathComponents enumerateObjectsUsingBlock:^(NSString *component, NSUInteger idx, __unused BOOL *stop) { NSString *intermediateURLString = [[[pathComponents subarrayWithRange:NSMakeRange(0, idx)] arrayByAddingObject:component] componentsJoinedByString:@"/"]; - [strongSelf MKCOL:intermediateURLString success:^(__unused AFHTTPRequestOperation *MKCOLOperation, __unused NSURLResponse *MKCOLResponse) { - - } failure:^(__unused AFHTTPRequestOperation *MKCOLOperation, NSError *MKCOLError) { + //[strongSelf MKCOL:intermediateURLString success:^(__unused AFHTTPRequestOperation *MKCOLOperation, __unused NSURLResponse *MKCOLResponse) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + [strongSelf MKCOL:intermediateURLString success:^(__unused NSURLSessionDataTask *MKCOLOperation, __unused NSURLResponse *MKCOLResponse) { + + + //} failure:^(__unused AFHTTPRequestOperation *MKCOLOperation, NSError *MKCOLError) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + } failure:^(__unused NSURLSessionDataTask *MKCOLOperation, NSError *MKCOLError) { + if (completionHandler) { completionHandler(nil, MKCOLError); } @@ -140,15 +202,36 @@ - (void)createFileAtURLString:(NSString *)URLString contents:(NSData *)contents completionHandler:(void (^)(NSURL *fileURL, NSError *error))completionHandler { + NSString *dataJSONString = [StringUtil jsonStringWith:contents]; + NSDictionary *attributesDataToPut = @{@"" : dataJSONString?:@""}; + __weak __typeof(self) weakself = self; - [self PUT:URLString data:contents success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { + //[self PUT:URLString data:contents success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + [self multiPUT:URLString tokenDic:nil extraHeaderDic:nil dataType:nil attributesData:attributesDataToPut success:^(NSURLSessionDataTask *task, __unused id responseObject) { + if (completionHandler) { - completionHandler([operation.response URL], nil); + completionHandler([task.response URL], nil); } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + //} failure:^(AFHTTPRequestOperation *operation, NSError *error) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + } failure:^(NSURLSessionDataTask *task, NSError *error) { + __strong __typeof(weakself) strongSelf = weakself; - if ([operation.response statusCode] == 409 && createIntermediateDirectories) { - NSArray *pathComponents = [[operation.request URL] pathComponents]; + + NSInteger statusCode = 0; + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)(task.response); + if ([httpResponse isKindOfClass:[NSHTTPURLResponse class]]) { + statusCode = httpResponse.statusCode; + } + + //if ([operation.response statusCode] == 409 && createIntermediateDirectories) { + if (statusCode == 409 && createIntermediateDirectories) { + + //NSArray *pathComponents = [[operation.request URL] pathComponents]; + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + NSArray *pathComponents = [[task.originalRequest URL] pathComponents]; + if ([pathComponents count] > 1) { [strongSelf createDirectoryAtURLString:[[pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents count] - 1)] componentsJoinedByString:@"/"] withIntermediateDirectories:YES completionHandler:^(__unused NSURL *directoryURL, NSError *MKCOLError) { if (MKCOLError) { @@ -168,18 +251,100 @@ - (void)createFileAtURLString:(NSString *)URLString }]; } -- (void)removeFileAtURLString:(NSString *)URLString - completionHandler:(void (^)(NSURL *fileURL, NSError *error))completionHandler + +/** + modify by OYXJ on 2016.08 + */ +- (NSURLSessionDataTask *)removeFileAtURLString:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + extraHeaderDic:(NSDictionary *)extraHeaderDic //request的HTTPHeaderField + dataType:(NSString *)dataType //数据类型 + attributesData:(NSDictionary *)attributesDataToDelete //数据项 + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { - [self DELETE:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { - if (completionHandler) { - completionHandler([operation.response URL], nil); - } - } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { - if (completionHandler) { - completionHandler(nil, error); + NSMutableString *mutableXMLString = [NSMutableString stringWithString:AFWebDAVXMLDeclarationString]; + { + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:[NSString stringWithFormat:@" 0) {//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns:%@=\"%@\"", abbreviation, namespace]; + }else{//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns=\"%@\"", namespace]; + } + }]; + [mutableXMLString appendString:@">"]; + + if (attributesDataToDelete) { + { + /* e.g. /sync/new/xxx0.json */ + [attributesDataToDelete enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull attributes, NSString * _Nonnull dataJSONString, BOOL * _Nonnull stop) { + [mutableXMLString appendString: @""]; + [mutableXMLString appendString: dataJSONString]; + [mutableXMLString appendString: @""]; + }]; + } } - }]; + + + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:[NSString stringWithFormat:@"",dataType]]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D", dataType]]; + } + + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"DELETE" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + + [request setValue:AFWebDAVStringForDepth(AFWebDAVZeroDepth) forHTTPHeaderField:@"Depth"]; + [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; + [request setHTTPBody:[mutableXMLString dataUsingEncoding:NSUTF8StringEncoding]]; + if (tokenDic.count == 1) {//token + [tokenDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } + if (extraHeaderDic.count > 0) {//extraHeaderDic + [extraHeaderDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } + + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; + [self.operationQueue addOperation:operation]; + + return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } - (void)moveItemAtURLString:(NSString *)originURLString @@ -187,11 +352,17 @@ - (void)moveItemAtURLString:(NSString *)originURLString overwrite:(BOOL)overwrite completionHandler:(void (^)(NSURL *fileURL, NSError *error))completionHandler { - [self MOVE:originURLString destination:destinationURLString overwrite:overwrite conditions:nil success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { + //[self MOVE:originURLString destination:destinationURLString overwrite:overwrite conditions:nil success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + [self MOVE:originURLString destination:destinationURLString overwrite:overwrite conditions:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) { + if (completionHandler) { - completionHandler([operation.response URL], nil); + completionHandler([task.response URL], nil); } - } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + //} failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + } failure:^(__unused NSURLSessionDataTask *task, NSError *error) { + if (completionHandler) { completionHandler(nil, error); } @@ -203,11 +374,17 @@ - (void)copyItemAtURLString:(NSString *)originURLString overwrite:(BOOL)overwrite completionHandler:(void (^)(NSURL *fileURL, NSError *error))completionHandler { - [self COPY:originURLString destination:destinationURLString overwrite:overwrite conditions:nil success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { + //[self COPY:originURLString destination:destinationURLString overwrite:overwrite conditions:nil success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + [self COPY:originURLString destination:destinationURLString overwrite:overwrite conditions:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) { + if (completionHandler) { - completionHandler([operation.response URL], nil); + completionHandler([task.response URL], nil); } - } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + //} failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + } failure:^(__unused NSURLSessionDataTask *task, NSError *error) { + if (completionHandler) { completionHandler(nil, error); } @@ -217,11 +394,37 @@ - (void)copyItemAtURLString:(NSString *)originURLString - (void)contentsOfFileAtURLString:(NSString *)URLString completionHandler:(void (^)(NSData *contents, NSError *error))completionHandler { - [self GET:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { - if (completionHandler) { - completionHandler(operation.responseData, nil); - } - } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + //[self GET:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, __unused id responseObject) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + [self GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) { + + /** + 此处做法的依据 AFNetworking内部实现: + 在task完成(complete)之后,首先 执行completionHandler,然后 抛出通知AFNetworkingTaskDidCompleteNotification。 + */ + + __block __weak id curTaskObserver; + curTaskObserver = [[NSNotificationCenter defaultCenter] addObserverForName: AFNetworkingTaskDidCompleteNotification + object: task + queue: nil + usingBlock: ^(NSNotification * _Nonnull note) { + if (completionHandler) { + + NSData *aData = [note userInfo][AFNetworkingTaskDidCompleteResponseDataKey]; + + completionHandler(aData, nil); + } + + // 这种方式,将导致 当前通知,只能调用一次。 + NSLog(@"attention here: run once, and only once!"); + [[NSNotificationCenter defaultCenter] removeObserver:curTaskObserver]; + curTaskObserver = nil;//这个重要,如果不是 __weak 。 + }]; + + //} failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { + /* replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 */ + } failure:^(__unused NSURLSessionDataTask *task, NSError *error) { + if (completionHandler) { completionHandler(nil, error); } @@ -229,51 +432,261 @@ - (void)contentsOfFileAtURLString:(NSString *)URLString } #pragma mark - +/* +replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 - (AFHTTPRequestOperation *)PUT:(NSString *)URLString data:(NSData *)data success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + + modify by OYXJ on 2016.08 + */ +- (NSURLSessionDataTask *)multiPUT:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + extraHeaderDic:(NSDictionary *)extraHeaderDic //request的HTTPHeaderField + dataType:(NSString *)dataType //数据类型 + attributesData:(NSDictionary *)attributesDataToPut //数据项 + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { + NSMutableString *mutableXMLString = [NSMutableString stringWithString:AFWebDAVXMLDeclarationString]; + { + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:[NSString stringWithFormat:@" 0) {//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns:%@=\"%@\"", abbreviation, namespace]; + }else{//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns=\"%@\"", namespace]; + } + }]; + [mutableXMLString appendString:@">"]; + + if (attributesDataToPut) { + { + /* e.g. xxx */ + [attributesDataToPut enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull attributes, NSString * _Nonnull dataJSONString, BOOL * _Nonnull stop) { + [mutableXMLString appendString: @""]; + [mutableXMLString appendString: dataJSONString]; + [mutableXMLString appendString: @""]; + }]; + } + } + + + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:[NSString stringWithFormat:@"",dataType]]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D", dataType]]; + } + + LELOGI(@"mutableXMlString = %@",mutableXMLString); + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PUT" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; - request.HTTPBody = data; - + + [request setValue:AFWebDAVStringForDepth(AFWebDAVZeroDepth) forHTTPHeaderField:@"Depth"]; + [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; + [request setHTTPBody:[mutableXMLString dataUsingEncoding:NSUTF8StringEncoding]]; + if (tokenDic.count == 1) {//token + [tokenDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } + if (extraHeaderDic.count > 0) {//extraHeaderDic + [extraHeaderDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } + +#if defined( DEBUG ) + // TODO: test code + // [request setValue:@"example.domain.com" forHTTPHeaderField:@"host"]; +#endif + + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; + */ + + LELOGI(@"request == %@",request); + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)PUT:(NSString *)URLString file:(NSURL *)fileURL success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + + modify by OYXJ on 2016.08 + */ +- (NSURLSessionDataTask *)multiPUT:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + extraHeaderDic:(NSDictionary *)extraHeaderDic //request的HTTPHeaderField + dataType:(NSString *)dataType //数据类型 + file:(NSURL *)fileURL + attributesData:(NSDictionary *)attributesDataToPut //数据项 + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSParameterAssert(fileURL && [fileURL isFileURL]); + NSMutableString *mutableXMLString = [NSMutableString stringWithString:AFWebDAVXMLDeclarationString]; + { + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:[NSString stringWithFormat:@" 0) {//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns:%@=\"%@\"", abbreviation, namespace]; + }else{//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns=\"%@\"", namespace]; + } + }]; + [mutableXMLString appendString:@">"]; + + if (attributesDataToPut) { + { + /* e.g. xxx */ + [attributesDataToPut enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull attributes, NSString * _Nonnull dataJSONString, BOOL * _Nonnull stop) { + [mutableXMLString appendString: @""]; + [mutableXMLString appendString: dataJSONString]; + [mutableXMLString appendString: @""]; + }]; + } + } + + + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:[NSString stringWithFormat:@"",dataType]]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D", dataType]]; + } + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PUT" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; - request.HTTPBodyStream = [NSInputStream inputStreamWithURL:fileURL]; + + [request setValue:AFWebDAVStringForDepth(AFWebDAVZeroDepth) forHTTPHeaderField:@"Depth"]; + [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; + [request setHTTPBody:[mutableXMLString dataUsingEncoding:NSUTF8StringEncoding]]; // TODO: setHTTPBody + request.HTTPBodyStream = [NSInputStream inputStreamWithURL:fileURL]; // TODO: HTTPBodyStream + if (tokenDic.count == 1) {//token + [tokenDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } + if (extraHeaderDic.count > 0) {//extraHeaderDic + [extraHeaderDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } +#if defined( DEBUG ) + // TODO: test code + // [request setValue:@"example.domain.com" forHTTPHeaderField:@"host"]; +#endif + + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } #pragma mark - +/* +replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 - (AFHTTPRequestOperation *)PROPFIND:(NSString *)URLString propertyNames:(NSArray *)propertyNames depth:(AFWebDAVDepth)depth success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + + modify by OYXJ on 2016.08 + */ +- (NSURLSessionDataTask *)PROPFIND:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + propertyNames:(NSArray *)propertyNames //要获取的数据项 + depth:(AFWebDAVDepth)depth + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSMutableString *mutableXMLString = [NSMutableString stringWithString:AFWebDAVXMLDeclarationString]; { - [mutableXMLString appendString:@" 0) {//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns:%@=\"%@\"", abbreviation, namespace]; + }else{//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns=\"%@\"", namespace]; + } }]; [mutableXMLString appendString:@">"]; @@ -282,39 +695,344 @@ - (AFHTTPRequestOperation *)PROPFIND:(NSString *)URLString [mutableXMLString appendFormat:@"<%@/>", property]; }]; } else { - [mutableXMLString appendString:@""]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:@""]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"<%@:allprop/>", self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; } - [mutableXMLString appendString:@""]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:@""]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; } - NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PROPFIND" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PROPFIND" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + */ + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PROPFIND" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + [request setValue:AFWebDAVStringForDepth(depth) forHTTPHeaderField:@"Depth"]; - [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type:"]; + [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:[mutableXMLString dataUsingEncoding:NSUTF8StringEncoding]]; + if (tokenDic.count == 1) {//token + [tokenDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } +#if defined( DEBUG ) + // TODO: test code + // [request setValue:@"example.domain.com" forHTTPHeaderField:@"host"]; +#endif + + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; + + return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; +} - return operation; +/** + GET + + @param URLString <#URLString description#> + @param tokenDic <#tokenDic description#> + + @return <#return value description#> + + add by OYXJ on 2016.10 + */ +- (NSURLSessionDataTask *)GET:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{@"token", tokenStr} + dataType:(NSString *)dataType //数据类型 + pathList:(NSArray *)pathsToGet //数据路径 + depth:(AFWebDAVDepth)depth + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSDictionary *parameters = nil; + void (^uploadProgressBlock)(NSProgress *uploadProgress) = nil; + void (^downloadProgressBlock)(NSProgress *downloadProgress) = nil; + + +// NSMutableString *mutableXMLString = [NSMutableString stringWithString:AFWebDAVXMLDeclarationString]; +// { +// /** +// add by OYXJ, considering that: XML Namespace not always 'D' +// +// [mutableXMLString appendString:[NSString stringWithFormat:@" 0) {//天坑,补一下。 +// [mutableXMLString appendFormat:@" xmlns:%@=\"%@\"", abbreviation, namespace]; +// }else{//天坑,补一下。 +// [mutableXMLString appendFormat:@" xmlns=\"%@\"", namespace]; +// } +// }]; +// [mutableXMLString appendString:@">"]; +// +// /* +// if (propertiesToGet) { +// [mutableXMLString appendString:@""]; +// { +// [propertiesToGet enumerateObjectsUsingBlock:^(NSString *property, __unused NSUInteger idx, __unused BOOL *stop) { +// [mutableXMLString appendFormat:@"<%@/>", property]; +// }]; +// } +// [mutableXMLString appendString:@""]; +// } +// */ +// +// if (pathsToGet) { +// { +// [pathsToGet enumerateObjectsUsingBlock:^(NSString *path, NSUInteger idx, BOOL * _Nonnull stop) { +// [mutableXMLString appendString:@""]; +// [mutableXMLString appendString:path]; +// [mutableXMLString appendString:@""]; +// }]; +// } +// } +// +// /** +// add by OYXJ, considering that: XML Namespace not always 'D' +// +// [mutableXMLString appendString:[NSString stringWithFormat:@"",dataType]]; +// */ +// [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D", dataType]]; +// } + +// LELOGD(@"mutableXMLString-----%@",mutableXMLString); + NSError *serializationError = nil; + NSMutableURLRequest *request = [self.requestSerializer + requestWithMethod: @"GET" + URLString: [[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] + parameters: parameters + error: &serializationError]; + if (serializationError) { + if (failure) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ + failure(nil, serializationError); + }); +#pragma clang diagnostic pop + } + + return nil; + } + + + + [request setValue:AFWebDAVStringForDepth(depth) forHTTPHeaderField:@"Depth"]; + [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; +// [request setHTTPBody:[mutableXMLString dataUsingEncoding:NSUTF8StringEncoding]]; + if (tokenDic.count == 1) {//token + [tokenDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } + +#if defined( DEBUG ) + // TODO: test code + // [request setValue:@"example.domain.com" forHTTPHeaderField:@"host"]; +#endif + + + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + uploadProgress: uploadProgressBlock + downloadProgress: downloadProgressBlock + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + LELOGD(@"GETresponse--%@\nresponseObject--%@\nerror--%@",response,responseObject,error); + }]; + + [dataTask resume]; + + return dataTask; } + +/** + * 获取完整的数据 + * + * @param URLString 服务器地址 + * @param tokenDic 用户token + * + * @return NSURLSessionDataTask* + + modify by OYXJ on 2016.08 + */ +- (NSURLSessionDataTask *)REPORT:(NSString *)URLString + tokenDic:(NSDictionary *)tokenDic //e.g. @{"token", tokenStr}; + dataType:(NSString *)dataType //数据类型 + propertyNames:(NSArray *)propertiesToGet //要获取的数据项 + pathList:(NSArray *)pathsToGet //数据路径 + depth:(AFWebDAVDepth)depth + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSMutableString *mutableXMLString = [NSMutableString stringWithString:AFWebDAVXMLDeclarationString]; + { + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:[NSString stringWithFormat:@" 0) {//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns:%@=\"%@\"", abbreviation, namespace]; + }else{//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns=\"%@\"", namespace]; + } + }]; + [mutableXMLString appendString:@">"]; + + if (propertiesToGet) { + [mutableXMLString appendString:@""]; + { + [propertiesToGet enumerateObjectsUsingBlock:^(NSString *property, __unused NSUInteger idx, __unused BOOL *stop) { + [mutableXMLString appendFormat:@"<%@/>", property]; + }]; + } + [mutableXMLString appendString:@""]; + } + + if (pathsToGet) { + { + [pathsToGet enumerateObjectsUsingBlock:^(NSString *path, NSUInteger idx, BOOL * _Nonnull stop) { + [mutableXMLString appendString:@""]; + [mutableXMLString appendString:path]; + [mutableXMLString appendString:@""]; + }]; + } + } + + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:[NSString stringWithFormat:@"",dataType]]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D", dataType]]; + } + + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"REPORT" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + + [request setValue:AFWebDAVStringForDepth(depth) forHTTPHeaderField:@"Depth"]; + [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; + [request setHTTPBody:[mutableXMLString dataUsingEncoding:NSUTF8StringEncoding]]; + if (tokenDic.count == 1) {//token + [tokenDic enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) { + [request setValue:obj forHTTPHeaderField:key]; + }]; + } + +#if defined( DEBUG ) + // TODO: test code + // [request setValue:@"example.domain.com" forHTTPHeaderField:@"host"]; +#endif + + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; +} + + + + +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)PROPPATCH:(NSString *)URLString set:(NSDictionary *)propertiesToSet remove:(NSArray *)propertiesToRemove success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + */ +- (NSURLSessionDataTask *)PROPPATCH:(NSString *)URLString + set:(NSDictionary *)propertiesToSet + remove:(NSArray *)propertiesToRemove + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSMutableString *mutableXMLString = [NSMutableString stringWithString:AFWebDAVXMLDeclarationString]; { - [mutableXMLString appendString:@" 0) {//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns:%@=\"%@\"", abbreviation, namespace]; + }else{//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns=\"%@\"", namespace]; + } }]; [mutableXMLString appendString:@">"]; if (propertiesToSet) { - [mutableXMLString appendString:@""]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:@""]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"<%@:set>", self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; { [propertiesToSet enumerateKeysAndObjectsUsingBlock:^(NSString *property, id value, __unused BOOL *stop) { [mutableXMLString appendFormat:@"<%@>", property]; @@ -322,84 +1040,264 @@ - (AFHTTPRequestOperation *)PROPPATCH:(NSString *)URLString [mutableXMLString appendFormat:@"", property]; }]; } - [mutableXMLString appendString:@""]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:@""]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; } if (propertiesToRemove) { - [mutableXMLString appendString:@""]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:@""]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"<%@:remove>", self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; { [propertiesToRemove enumerateObjectsUsingBlock:^(NSString *property, __unused NSUInteger idx, __unused BOOL *stop) { - [mutableXMLString appendFormat:@"<%@/>", property]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendFormat:@"<%@/>", property]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"<%@:prop><%@/>", self.defaultAbbreviationOfXMLnamespaces?:@"D", property, self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; }]; } - [mutableXMLString appendString:@""]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:@""]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; } - [mutableXMLString appendString:@""]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:@""]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; } - NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PROPPATCH" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; - [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type:"]; + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PROPPATCH" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + */ + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PROPPATCH" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + + [request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:[mutableXMLString dataUsingEncoding:NSUTF8StringEncoding]]; + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)MKCOL:(NSString *)URLString success:(void (^)(AFHTTPRequestOperation *operation, NSURLResponse *response))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + */ +- (NSURLSessionDataTask *)MKCOL:(NSString *)URLString + success:(void (^)(NSURLSessionDataTask *task, NSURLResponse *response))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { - NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"MKCOL" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"MKCOL" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + */ + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"MKCOL" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)COPY:(NSString *)sourceURLString destination:(NSString *)destinationURLString overwrite:(BOOL)overwrite conditions:(NSString *)IfHeaderFieldValue success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + */ +- (NSURLSessionDataTask *)COPY:(NSString *)sourceURLString + destination:(NSString *)destinationURLString + overwrite:(BOOL)overwrite + conditions:(NSString *)IfHeaderFieldValue + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { - NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"COPY" URLString:[[self.baseURL URLByAppendingPathComponent:sourceURLString] absoluteString] parameters:nil error:nil]; - [request setValue:[[self.baseURL URLByAppendingPathComponent:destinationURLString] absoluteString] forHTTPHeaderField:@"Destination"]; + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"COPY" URLString:[[self.baseURL URLByAppendingPathComponent:sourceURLString] absoluteString] parameters:nil error:nil]; + */ + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"COPY" URLString:[[NSURL URLWithString:sourceURLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + [request setValue:[[self.baseURL URLByAppendingPathComponent:destinationURLString] absoluteString] forHTTPHeaderField:@"Destination"]; + */ + [request setValue:[[NSURL URLWithString:destinationURLString relativeToURL:self.baseURL] absoluteString] forHTTPHeaderField:@"Destination"]; + + [request setValue:(overwrite ? @"T" : @"F") forHTTPHeaderField:@"Overwrite"]; if (IfHeaderFieldValue) { [request setValue:IfHeaderFieldValue forHTTPHeaderField:@"If"]; } + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)MOVE:(NSString *)sourceURLString destination:(NSString *)destinationURLString overwrite:(BOOL)overwrite conditions:(NSString *)IfHeaderFieldValue success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + */ +- (NSURLSessionDataTask *)MOVE:(NSString *)sourceURLString + destination:(NSString *)destinationURLString + overwrite:(BOOL)overwrite + conditions:(NSString *)IfHeaderFieldValue + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { - NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"MOVE" URLString:[[self.baseURL URLByAppendingPathComponent:sourceURLString] absoluteString] parameters:nil error:nil]; - [request setValue:[[self.baseURL URLByAppendingPathComponent:destinationURLString] absoluteString] forHTTPHeaderField:@"Destination"]; + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"MOVE" URLString:[[self.baseURL URLByAppendingPathComponent:sourceURLString] absoluteString] parameters:nil error:nil]; + */ + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"MOVE" URLString:[[NSURL URLWithString:sourceURLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + [request setValue:[[self.baseURL URLByAppendingPathComponent:destinationURLString] absoluteString] forHTTPHeaderField:@"Destination"]; + */ + [request setValue:[[NSURL URLWithString:destinationURLString relativeToURL:self.baseURL] absoluteString] forHTTPHeaderField:@"Destination"]; + [request setValue:(overwrite ? @"T" : @"F") forHTTPHeaderField:@"Overwrite"]; if (IfHeaderFieldValue) { [request setValue:IfHeaderFieldValue forHTTPHeaderField:@"If"]; } + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } + +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)LOCK:(NSString *)URLString timeout:(NSTimeInterval)timeoutInterval depth:(AFWebDAVDepth)depth @@ -408,48 +1306,162 @@ - (AFHTTPRequestOperation *)LOCK:(NSString *)URLString owner:(NSURL *)ownerURL success:(void (^)(AFHTTPRequestOperation *operation, NSString *lockToken))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + */ +- (NSURLSessionDataTask *)LOCK:(NSString *)URLString + timeout:(NSTimeInterval)timeoutInterval + depth:(AFWebDAVDepth)depth + scope:(AFWebDAVLockScope)scope + type:(AFWebDAVLockType)type + owner:(NSURL *)ownerURL + success:(void (^)(NSURLSessionDataTask *task, NSString *lockToken))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSMutableString *mutableXMLString = [NSMutableString stringWithString:AFWebDAVXMLDeclarationString]; { - [mutableXMLString appendString:@" 0) {//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns:%@=\"%@\"", abbreviation, namespace]; + }else{//天坑,补一下。 + [mutableXMLString appendFormat:@" xmlns=\"%@\"", namespace]; + } }]; [mutableXMLString appendString:@">"]; - [mutableXMLString appendFormat:@"", AFWebDAVStringForLockScope(scope)]; - [mutableXMLString appendFormat:@"", AFWebDAVStringForLockType(type)]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendFormat:@"", AFWebDAVStringForLockScope(scope)]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"<%@:lockscope><%@:%@/>", + self.defaultAbbreviationOfXMLnamespaces?:@"D", + self.defaultAbbreviationOfXMLnamespaces?:@"D",AFWebDAVStringForLockScope(scope), + self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; + + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendFormat:@"", AFWebDAVStringForLockType(type)]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"<%@:locktype><%@:%@/>", + self.defaultAbbreviationOfXMLnamespaces?:@"D", + self.defaultAbbreviationOfXMLnamespaces?:@"D",AFWebDAVStringForLockType(type), + self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; if (ownerURL) { - [mutableXMLString appendFormat:@"%@", [ownerURL absoluteString]]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendFormat:@"%@", [ownerURL absoluteString]]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"<%@:owner><%@:href>%@", + self.defaultAbbreviationOfXMLnamespaces?:@"D", + self.defaultAbbreviationOfXMLnamespaces?:@"D", + [ownerURL absoluteString], + self.defaultAbbreviationOfXMLnamespaces?:@"D", + self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; } - [mutableXMLString appendString:@""]; + /** + add by OYXJ, considering that: XML Namespace not always 'D' + + [mutableXMLString appendString:@""]; + */ + [mutableXMLString appendString:[NSString stringWithFormat:@"", self.defaultAbbreviationOfXMLnamespaces?:@"D"]]; } - NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"LOCK" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"LOCK" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + */ + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"LOCK" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + [request setValue:AFWebDAVStringForDepth(depth) forHTTPHeaderField:@"Depth"]; if (timeoutInterval > 0) { [request setValue:[@(timeoutInterval) stringValue] forHTTPHeaderField:@"Timeout"]; } + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } +/* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + - (AFHTTPRequestOperation *)UNLOCK:(NSString *)URLString token:(NSString *)lockToken success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure + */ +- (NSURLSessionDataTask *)UNLOCK:(NSString *)URLString + token:(NSString *)lockToken + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { - NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"UNLOCK" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + /** + fix bug by OYXJ: request's params `URLString` become nil, when `self.baseURL` is init with nil (or never get init at all). + + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"UNLOCK" URLString:[[self.baseURL URLByAppendingPathComponent:URLString] absoluteString] parameters:nil error:nil]; + */ + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"UNLOCK" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; + [request setValue:lockToken forHTTPHeaderField:@"Lock-Token"]; + /* + replaced with NSURLSessionDataTask by OYXJ on 2016.08.08 + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self.operationQueue addOperation:operation]; return operation; + */ + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest: request + completionHandler: ^(NSURLResponse * __unused response, id responseObject, NSError *error) { + + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + + }]; + [dataTask resume]; + + return dataTask; } @end @@ -525,17 +1537,144 @@ @interface AFWebDAVMultiStatusResponse () @property (readwrite, nonatomic, assign) NSUInteger contentLength; @property (readwrite, nonatomic, copy) NSDate *creationDate; @property (readwrite, nonatomic, copy) NSDate *lastModifiedDate; + + +//! add by OYXJ, used to retrieve some wanted data of XML. +@property (readwrite, nonatomic, strong) ONOXMLElement *element;//strong + + +/** + begin --- 实现协议 WebDavResource --- begin + */ + +//! The `etag` of the resource at the response URL. +@property(nonatomic, copy, readwrite) NSString *etag; + +/** + 服务端资源的唯一id(主键) + */ +@property(nonatomic, copy, readwrite) NSString *name; // 相当于 source id + +//@property(nonatomic, copy, readonly) NSString *ctag; + +@property(nonatomic, strong, readwrite)NSDictionary *customProps; + +//private final Resourcetype resourceType; ??? +//private final String contentType; ??? TODO:: +//private final Long contentLength; ??? TODO:: + +@property(nonatomic, copy, readwrite) NSString *notedata; +@property(nonatomic, copy, readwrite) NSString *lastModified; +@property(nonatomic, copy, readwrite) NSString *deletedTime; +@property(nonatomic, copy, readwrite) NSString *deletedDataName; +@property(nonatomic, copy, readwrite) NSString *deleted; + +/** + end --- 实现协议 WebDavResource --- end + */ + + + @end + + @implementation AFWebDAVMultiStatusResponse +// by OYXJ +NSString * const getcontentlengthCONST = @"getcontentlength"; +NSString * const creationdateCONST = @"creationdate"; +NSString * const getlastmodifiedCONST = @"getlastmodified"; +NSString * const getetagCONST = @"getetag";//实现协议 WebDavResource + +// 实现协议 WebDavResource +NSString * const resourcetypeCONST = @"resourcetype"; +NSString * const getcontenttypeCONST = @"getcontenttype"; +NSString * const notedataCONST = @"notedata"; +NSString * const getDeletedTimeCONST = @"getDeletedTime"; +NSString * const getDeletedDataNameCONST = @"getDeletedDataName"; +NSString * const getDeletedCONST = @"getDeleted"; + + +#pragma mark - init + - (instancetype)initWithResponseElement:(ONOXMLElement *)element { NSParameterAssert(element); - NSString *href = [[element firstChildWithTag:@"href" inNamespace:@"D"] stringValue]; - NSInteger status = [[[element firstChildWithTag:@"status" inNamespace:@"D"] numberValue] integerValue]; + + /* + + /sync/chatcontacts/f5187830e27a4120bd17107c62011ba5 + + + W/"db3b4d0b9c05509d3967a56b4a0a0353" + {"source_id":"f5187830e27a4120bd17107c62011ba5","display_name":"vhs","phone_number":"13716750071#13716750075","is_voip_number":"1","account_phone_number":"13661248236","contact_type":0,"contact_from":0,"device_id":"--866647020047438"} + + HTTP/1.1 200 OK + + + */ + + /** + WebDav Response Namespace not always 'D' + Ref.: https://github.com/BitSuites/AFWebDAVManager/commit/c25abdb71e07897212b44212e2d854e744a64048 + rocket0423 committed on 10 Jul 2015 + 1 parent 45504c7 commit c25abdb71e07897212b44212e2d854e744a64048 + + NSString *href = [[element firstChildWithTag:@"href" inNamespace:@"D"] stringValue]; + NSInteger status = [[[element firstChildWithTag:@"status" inNamespace:@"D"] numberValue] integerValue]; + */ + NSString *href = [[element firstChildWithTag:@"href"] stringValue]; + NSInteger status = [[[element firstChildWithTag:@"status"] numberValue] integerValue]; + + if (status == 0) {//[begin] fix bug: `status code` not found in firstChild element. + NSString *statusString = [[[element firstChildWithTag:@"propstat"] firstChildWithTag:@"status"] stringValue]; + statusString = [statusString stringByReplacingOccurrencesOfString:@"HTTP/1.1" withString:@""]; + statusString = [statusString stringByTrimmingCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]]; + statusString = [statusString stringByTrimmingCharactersInSet:[NSCharacterSet letterCharacterSet]]; + statusString = [statusString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if (statusString.length > 0) { + if ([statusString integerValue] > 0) { + status = [statusString integerValue]; + } + } + }//[end] fix bug: `status code` not found in firstChild element. + + self = [self initWithURL:[NSURL URLWithString:href] statusCode:status HTTPVersion:@"HTTP/1.1" headerFields:nil]; + {//element + //TODO: A true deep copy http://stackoverflow.com/questions/647260/deep-copying-an-nsarray + self.element = element;//strong reference + {//解析数据---begin// + NSDictionary *atts = [element attributes]; + if (atts.count > 0) { + //开源库Ono + self.customProps = atts; + }else{ + //自己 解析数据 + ONOXMLElement *propElement = [[element firstChildWithTag:@"propstat"] firstChildWithTag:@"prop"]; + + + NSMutableDictionary *proDic = [NSMutableDictionary dictionaryWithCapacity:2]; + + NSArray *childrenElements = [propElement children]; + for (int i = 0; i < childrenElements.count; i++) { + ONOXMLElement *e = childrenElements[i]; + NSString *aTag = [e tag]; + NSString *stringValue = [self valueOfTag: aTag + inElement: e]; + if (aTag.length && stringValue.length) { + [proDic setObject:stringValue forKey:aTag]; + } + } + + DDLogVerbose(@"%@", proDic); + + self.customProps = proDic; + } + }//解析数据---end// + }//element if (!self) { return nil; } @@ -548,11 +1687,279 @@ - (instancetype)initWithResponseElement:(ONOXMLElement *)element { } } + + /** + WebDav Response Namespace not always 'D' + Ref.: https://github.com/BitSuites/AFWebDAVManager/commit/c25abdb71e07897212b44212e2d854e744a64048 + rocket0423 committed on 10 Jul 2015 + 1 parent 45504c7 commit c25abdb71e07897212b44212e2d854e744a64048 + self.contentLength = [[[propElement firstChildWithTag:@"getcontentlength" inNamespace:@"D"] numberValue] unsignedIntegerValue]; self.creationDate = [[propElement firstChildWithTag:@"creationdate" inNamespace:@"D"] dateValue]; self.lastModifiedDate = [[propElement firstChildWithTag:@"getlastmodified" inNamespace:@"D"] dateValue]; - + */ + + + //by OYXJ + NSString *ns = [propElement namespace]; + NSMutableArray *beginEndTAGs = [NSMutableArray arrayWithCapacity:2]; + NSArray * const tags = @[getcontentlengthCONST,creationdateCONST,getlastmodifiedCONST,getetagCONST]; + [tags enumerateObjectsUsingBlock:^(id _Nonnull eachTag, NSUInteger idx, BOOL * _Nonnull stop) { + NSString *beginTAG = [NSString stringWithFormat:@"<%@:%@>", ns,eachTag]; + NSString *endTAG = [NSString stringWithFormat:@"", ns,eachTag]; + [beginEndTAGs addObject: beginTAG]; + [beginEndTAGs addObject: endTAG]; + }]; + + + {//getcontentlength + self.contentLength = [[[propElement firstChildWithTag:getcontentlengthCONST] + numberValue] unsignedIntegerValue]; + if (self.contentLength==0) {//by OYXJ + NSMutableString *contentLengthSTR = [[[propElement firstChildWithTag:getcontentlengthCONST] + stringValue] mutableCopy]; + [beginEndTAGs enumerateObjectsUsingBlock:^(id _Nonnull aTAG, NSUInteger idx, BOOL * _Nonnull stop) { + [contentLengthSTR replaceOccurrencesOfString:aTAG + withString:@"" + options:NSLiteralSearch + range:NSMakeRange(0, contentLengthSTR.length)]; + }]; + + NSNumber *aContentLength = [propElement.document.numberFormatter numberFromString:contentLengthSTR]; + + self.contentLength = [aContentLength unsignedIntegerValue]; + } + }//getcontentlength + + {//creationdate + self.creationDate = [[propElement firstChildWithTag:creationdateCONST] dateValue]; + if (self.creationDate==nil) {//by OYXJ + NSMutableString *creationDateSTR = [[[propElement firstChildWithTag:creationdateCONST] + stringValue] mutableCopy]; + [beginEndTAGs enumerateObjectsUsingBlock:^(id _Nonnull aTAG, NSUInteger idx, BOOL * _Nonnull stop) { + [creationDateSTR replaceOccurrencesOfString:aTAG + withString:@"" + options:NSLiteralSearch + range:NSMakeRange(0, creationDateSTR.length)]; + }]; + + NSDate *aCreationDate = [propElement.document.dateFormatter dateFromString:creationDateSTR]; + if (aCreationDate==nil) { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + //[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];//by OYXJ + //[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];//by OYXJ + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];//by OYXJ + + aCreationDate = [dateFormatter dateFromString:creationDateSTR]; + } + + self.creationDate = aCreationDate; + } + }//creationdate + + + {//getlastmodified + self.lastModifiedDate = [[propElement firstChildWithTag:getlastmodifiedCONST] dateValue]; + if (self.lastModifiedDate==nil) {//by OYXJ + NSMutableString *lastModifiedDateSTR = [[[propElement firstChildWithTag:getlastmodifiedCONST] + stringValue] mutableCopy]; + [beginEndTAGs enumerateObjectsUsingBlock:^(id _Nonnull aTAG, NSUInteger idx, BOOL * _Nonnull stop) { + [lastModifiedDateSTR replaceOccurrencesOfString:aTAG + withString:@"" + options:NSLiteralSearch + range:NSMakeRange(0, lastModifiedDateSTR.length)]; + }]; + + NSDate *aLastModifiedDate = [propElement.document.dateFormatter dateFromString:lastModifiedDateSTR]; + if (aLastModifiedDate==nil) { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + //[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];//by OYXJ + //[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];//by OYXJ + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];//by OYXJ + + aLastModifiedDate = [dateFormatter dateFromString:lastModifiedDateSTR]; + } + + self.lastModifiedDate = aLastModifiedDate; + } + }//getlastmodified + + + {//getetag + NSMutableString *aEtagSTR = [[[propElement firstChildWithTag:getetagCONST] + stringValue] mutableCopy]; + [beginEndTAGs enumerateObjectsUsingBlock:^(id _Nonnull aTAG, NSUInteger idx, BOOL * _Nonnull stop) { + [aEtagSTR replaceOccurrencesOfString:aTAG + withString:@"" + options:NSLiteralSearch + range:NSMakeRange(0, aEtagSTR.length)]; + }]; + + self.etag = [aEtagSTR copy]; + }//getetag + + return self; } + +#pragma mark - private + +/** + 根据标签名字,获取标签的值 + 特别注意,标签的值,是String类型,才使用此方法。 + + @param aTagNameCONST 标签名字,使用此类中定义的 常量字符串 + + @return 标签的值 + */ +- (NSString *)valueOfTag:(NSString *)aTagNameCONST inElement:(ONOXMLElement *)anElement +{ + if (aTagNameCONST.length <= 0) { + return nil; + } + if (anElement == nil) { + return nil; + } + + NSString *returnStr = nil; + @try { + //Code that can potentially throw an exception + + NSMutableString *aTagValueSTR = [[anElement stringValue] mutableCopy]; + + + if ([aTagValueSTR rangeOfString:aTagNameCONST].location == NSNotFound) { + // do nothing here ! + }else{ + + NSString *ns = [anElement namespace]; + NSMutableArray *beginEndTAGs = [NSMutableArray arrayWithCapacity:1]; + [@[aTagNameCONST] enumerateObjectsUsingBlock:^(id _Nonnull eachTag, NSUInteger idx, BOOL * _Nonnull stop) { + NSString *beginTAG = [NSString stringWithFormat:@"<%@:%@>", ns,eachTag]; + NSString *endTAG = [NSString stringWithFormat:@"", ns,eachTag]; + [beginEndTAGs addObject: beginTAG]; + [beginEndTAGs addObject: endTAG]; + }]; + + [beginEndTAGs enumerateObjectsUsingBlock:^(id _Nonnull aTAG, NSUInteger idx, BOOL * _Nonnull stop) { + [aTagValueSTR replaceOccurrencesOfString:aTAG + withString:@"" + options:NSLiteralSearch + range:NSMakeRange(0, aTagValueSTR.length)]; + }]; + } + + returnStr = [aTagValueSTR copy]; + + } @catch (NSException *exception) { + //Handle an exception thrown in the @try block + + NSLog(@"%@", exception); + + } @finally { + //Code that gets executed whether or not an exception is thrown + + return returnStr; + } + +} + + +#pragma mark - getters + +- (NSString *)etag +{ + return _etag; +} + +/** + 服务端资源的唯一id(主键) + 相当于 source id + */ +- (NSString *)name +{ + if (nil==_name) { + _name = self.URL.absoluteString.lastPathComponent ?: self.URL.absoluteString; + } + + return _name; +} + +//- (NSString *)ctag +//{ +// return _ctag; +//} + +- (NSDictionary *)customProps +{ + return _customProps; +} + +//private final Resourcetype resourceType; ??? +//private final String contentType; ??? TODO:: +//private final Long contentLength; ??? TODO:: + + + +- (NSString *)notedata +{ + if (nil==_notedata) { + + ONOXMLElement *propElement = [[self.element firstChildWithTag:@"propstat"] firstChildWithTag:@"prop"]; + _notedata = [self valueOfTag: notedataCONST + inElement: [propElement firstChildWithTag:notedataCONST]]; + } + + return _notedata; +} + +- (NSString *)lastModified +{ + if (nil==_lastModified) { + + _lastModified = [self.lastModifiedDate description]; + } + + return _lastModified; +} + +- (NSString *)deletedTime +{ + if (nil==_deletedTime) { + + ONOXMLElement *propElement = [[self.element firstChildWithTag:@"propstat"] firstChildWithTag:@"prop"]; + _deletedTime = [self valueOfTag: getDeletedTimeCONST + inElement: [propElement firstChildWithTag:getDeletedTimeCONST]]; + } + + return _deletedTime; +} + +- (NSString *)deletedDataName +{ + if (nil==_deletedDataName) { + + ONOXMLElement *propElement = [[self.element firstChildWithTag:@"propstat"] firstChildWithTag:@"prop"]; + _deletedDataName = [self valueOfTag: getDeletedDataNameCONST + inElement: [propElement firstChildWithTag:getDeletedDataNameCONST]]; + } + + return _deletedDataName; +} + +- (NSString *)deleted +{ + if (nil==_deleted) { + + ONOXMLElement *propElement = [[self.element firstChildWithTag:@"propstat"] firstChildWithTag:@"prop"]; + _deleted = [self valueOfTag: getDeletedCONST + inElement: [propElement firstChildWithTag:getDeletedCONST]]; + } + + return _deleted; +} + + @end + diff --git a/AFWebDAVManager/README.md b/AFWebDAVManager/README.md new file mode 100755 index 0000000..86da3ee --- /dev/null +++ b/AFWebDAVManager/README.md @@ -0,0 +1,49 @@ +# AFWebDAVManager + +`AFWebDAVManager` is an `AFHTTPRequestOperationManager` subclass for interacting with [WebDAV](http://en.wikipedia.org/wiki/WebDAV) servers. + +**Caution:** This code is still in its early stages of development, so exercise caution when incorporating this into production code. + +## Example Usage + +```objective-c +AFWebDAVManager *webDAVManager = [[AFWebDAVManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://example.com"]]; +webDAVManager.credential = [NSURLCredential credentialWithUser:@"username" + password:@"Pa55word" + persistence:NSURLCredentialPersistenceForSession]; + +[webDAVManager createFileAtURLString:@"/path/to/file.txt" + withIntermediateDirectories:YES + contents:[@"Hello, World" dataUsingEncoding:NSUTF8StringEncoding] + completionHandler:^(NSURL *fileURL, NSError *error) +{ + if (error) { + NSLog(@"[Error] %@", error); + } else { + NSLog(@"File created: %@", fileURL); + } +}]; + +[webDAVManager contentsOfDirectoryAtURLString:@"/path" + recursive:NO + completionHandler:^(NSArray *items, NSError *error) +{ + if (error) { + NSLog(@"[Error] %@", error); + } else { + NSLog(@"Items: %@", items); + } +}]; +``` + +## Contact + +Mattt Thompson + +- http://github.com/mattt +- http://twitter.com/mattt +- m@mattt.me + +## License + +AFWebDAVManager is available under the MIT license. See the LICENSE file for more info. From 465ca4c7ec8ccef1a5353e3cc898fcec0714c9ce Mon Sep 17 00:00:00 2001 From: HawkingOuYang Date: Sun, 20 Nov 2016 21:51:59 +0800 Subject: [PATCH 2/2] Update README.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 86da3ee..f0f2e2f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,24 @@ +modify by OYXJ on 2016.08 + +AFHTTPRequestOperation —> NSURLSessionDataTask + +XML formart via Ono + +the commit of code has been verified in a project of my company. SO IT WORKS ! + +P.S. ---> merge the following + +1、Fixed crash related to sending 'URL' selector to '_NSInlineData' inst… +thanks to @danielr +danielr@1ba182b + +2、WebDav Response Namespace not always 'D' +thanks to @BitSuites +BitSuites@c25abdb + +-------------------------------------------------------------------------------- + + # AFWebDAVManager `AFWebDAVManager` is an `AFHTTPRequestOperationManager` subclass for interacting with [WebDAV](http://en.wikipedia.org/wiki/WebDAV) servers.