因為工作上的需要,前后臺的接口對接使用的webService進行的。本人之前的對接經驗主要是webApi對接,返回JSON串進行處理。使用webService對接真心沒有經驗,更讓我尷尬的是我之前就沒聽過webService這個名詞??。因為工作的需要以及彌補自己的不足,研究一下AF使用webService的請求。本人寫的不好,大家多多見諒,希望能為同樣經歷的人提供一點幫助。
首先對AF進行初始化,我寫的二次封裝是繼承于AFHTTPSessionManager寫的。self與manager在調用方法上是一樣的。
//初始化
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
//設置請求類型
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
//設置請求超時時間
manager.requestSerializer.timeoutInterval = 30;
//設置這個的目的是返回信息成功后,信息為NSData類型,否則為NSXMLParser類型
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//這個一定要設置,否則會請求失敗
[manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
//我參考了其他人的經驗,但是以我的情況來說,使用“application/soap+xml”無法請求成功
// [manager.requestSerializer setValue:@"application/soap+xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"image/jpeg", @"text/plain", @"text/xml", nil];
這樣webService的設置基本完成了,接下來需要按照各自的接口協議對參數進行設置,外部接口仍然按照NSDictionary的形式傳進來,在二次封裝內部進行處理
****特別注意:BaseUrl并非是完整的請求地址,只是域名部分末尾有“/”
//url:請求地址 dictionary:請求參數 action:方法名 successObject:成功回調 failureObject:失敗回調 errorObject:異?;卣{
- (void)post_Url:(NSString *)url Param:(NSDictionary *)dictionary Action:(NSString *)action Success:(SuccessCompletedBlock)successObject Failure:(FailureCompletedBlock)failureObject Error:(ErrorCompletedBlock)errorObject {
NSMutableString *soapMutableStr = [self parameterToDealAction:action param:dictionary];
//請求發(fā)送到的路徑
[self.requestSerializer setValue:[NSString stringWithFormat:@"%zd", soapMutableStr.length] forHTTPHeaderField:@"Content-Length"];
//設置HTTPBody
[self.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
return soapMutableStr;
}];
//數據請求
[self POST:url parameters:soapMutableStr progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//responseObject 一個NSData類型的文件
//數據的返回的具體格式是JSON類型(與后臺協商后),需要封裝個方法提取并轉化為NSDictionary類型
NSDictionary *dict = [NSDictionary dictionaryWithDictionary:[CYTextTool webServiceDataExchangeDictionary:responseObject action:action]];
if (dict && [[dict objectForKey:@"status"] integerValue] == 0) {
//成功回調
if (successObject) {
successObject(dict);
}
}else {
//失敗回調
if (failureObject) {
failureObject(dict);
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//異?;卣{
if (error) {
errorObject(error);
}
}];
}
下面是對整體參數的封裝處理
- (NSMutableString *)parameterToDealAction:(NSString *)action param:(NSDictionary *)dictionary {
//Header為請求頭 MineSoapHeader為方法名 key為參數(宏,是前后臺內部定義的) BaseUrl為域名地址(宏)
NSString *headStr = [NSString stringWithFormat:
@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
"<soap:Header>\n"
"<MineSoapHeader xmlns=\"%@\">\n"
"<key>%@</key>\n"
"</MineSoapHeader>\n"
"</soap:Header>\n" , BaseUrl, APP_KEY
];
//參數拼接
NSMutableString *soapMutableStr = [NSMutableString stringWithString:headStr];
//判斷是否存在方法名
if (action.length > 0) {
//將body拼接上
[soapMutableStr appendString:[NSString stringWithFormat:@"<soap:Body>\n"
"<%@ xmlns=\"%@\">\n", action, BaseUrl]];
}
//判斷是否存在參數(如果存在參數一定會有方法名的)
if (dictionary) {
//將參數拼接進字符串中,格式<key>value</key>
for (NSString *key in dictionary) {
[soapMutableStr appendString:[NSString stringWithFormat:@"<%@>%@</%@>\n", key, [dictionary objectForKey:key], key]];
}
}
//拼接body結束符
if (action.length > 0) {
[soapMutableStr appendString:[NSString stringWithFormat:@"</%@>\n""</soap:Body>\n", action]];
}
//拼接整體請求結束符
[soapMutableStr appendString:@"</soap:Envelope>\n"];
return soapMutableStr;
}
請求成功后對返回的數據進行處理,CYTextTool是自定義的工具類
//將NSData轉化成NSDictionary
//data為返回文件 action為方法名
+ (NSDictionary *)webServiceDataExchangeDictionary:(NSData *)data action:(NSString *)action {
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// 利用正則表達式取出<action></action>之間的字符串
NSRegularExpression *regular = [[NSRegularExpression alloc] initWithPattern:[NSString stringWithFormat:@"(?<=%@Result\\>).*(?=</%@Result)", action, action] options:NSRegularExpressionCaseInsensitive error:nil];
//創(chuàng)建接收字典
NSDictionary *dic = [NSDictionary dictionary];
for (NSTextCheckingResult *checkingResult in [regular matchesInString:result options:0 range:NSMakeRange(0, result.length)]) {
// 得到字典
dic = [NSJSONSerialization JSONObjectWithData:[[result substringWithRange:checkingResult.range] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil];
}
return dic;
}