iOS Soap request 封裝 附github地址

SOAP 是一種簡單的基於 XML 的協議,它使應用程序通過 HTTP 來交換信息。

基礎知識學習: http://www.w3school.com.cn/soap/index.asp


HTML基本格式

 <?xml version="1.0"?>
 <soap:Envelope
 xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
 soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 
 <soap:Header>
 ...
 ...
 </soap:Header>
 
 <soap:Body>
 ...
 ...
 <soap:Fault>
 ...
 ...
 </soap:Fault>
 </soap:Body>
 
 </soap:Envelope>


 NSString *soapMessage =
 [NSString stringWithFormat:
 @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
 "<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/\">"
 "<soap:Body>"
 "<Save xmlns=\"http://www.myapp.com/\">"
 "<par1>%i</par1>"
 "<par2>%@</par2>"
 "<par3>%@</par3>"
 "</Save>"
 "</soap:Body>"
 "</soap:Envelope>", par1, par2, par3
 ];


提一點:動態看待所有代碼,不要死腦筋。另外額外說一點,soapMessage不要看得太死了,不同的服務器配置,自然soapMessage的要求不一樣。

後來一個同學問我他soap遇到的問題,經過我修改得出了其中一個soapMessage如下:

Content-Type: application/soap+xml; charset=utf-8 。而我這裏的是: text/xml;charset=utf-8  等等一些區別。所以要靈活運用。

 NSString *soapMessage = [NSString stringWithFormat:
                             @"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">"
                             
                             "<soap:Body>"
                             
                                "<UserRegister xmlns=\"http://tempuri.org/\">"
                                     "<sCheckCode>APP008</sCheckCode>"
                                     "<sUserNo>sdfsf</sUserNo>"
                                     "<sUserName>wqer</sUserName>"
                                     "<sUserPwd>t123456</sUserPwd>"
                                "</UserRegister>"
                             
                             "</soap:Body>"
                             
                             "</soap:Envelope>"];




//具體實現: github地址:https://github.com/tikeyc/TSoapRequest

typedef void (^ResultBlock) (id result,BOOL isDictionary,NSString *message);

- (NSURLConnection *)getDataAPIResultWithURL:(NSString *)url
                                      params:(NSMutableDictionary *)params
                                 htttpMethod:(NSString *)htttpMethod
                             withSOAPAction:(NSString *)soapAction
                             withMethodName:(NSString *)soapMethodName
                                withResultBlock:(ResultBlock)resultBock
{
    self.soapMethodName = soapMethodName;
    self.resultBlock = resultBock;
    
    ///////////
    //
    //    NSString *soapMessage = [NSString stringWithFormat:
    //                             @"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">"
    //                             "<soapenv:Header/>"
    //                             "<soapenv:Body>"
    //                             "<FZ_MB_RSL_INV_LKP_SRVC_OP>"
    //                             "<OPRID>%@</OPRID>"
    //                             "<PWD>%@</PWD>"
    //                             "<PORT>%@</PORT>"
    //                             "<MKT>%@</MKT>"
    //                             "<DVC>%@</DVC>"
    //                             "</FZ_MB_RSL_INV_LKP_SRVC_OP>"
    //                             "</soapenv:Body>"
    //                             "</soapenv:Envelope>",
    //                             @"WRSLDEMO",@"FLABC123",@"CNCAN",@"CHN",@"APH"];
///////////soapMessage 拼接
    NSString *soapHtmlHead = [NSString stringWithFormat:
                              @"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">"
                              "<soapenv:Header/>"
                              "<soapenv:Body>"
                              "<%@>",soapMethodName];
    NSString *soapHtmlFoot = [NSString stringWithFormat:
                              @"</%@>"
                              "</soapenv:Body>"
                              "</soapenv:Envelope>",soapMethodName];
    
    NSMutableString *soapHtmlMiddle = [NSMutableString string];
//    for (NSString *key in params.allKeys) {
//        NSString *value = params[key];
//        NSString *bodyString = [NSString stringWithFormat:@"<%@>%@</%@>",key,value,key];
//        [soapHtmlMiddle appendString:bodyString];
//    } 當包含多層key-value時,此法存在問題,所以運用下面的遞歸調用
    [self appendSoapHtmlMiddle:&soapHtmlMiddle WithParams:params];
    
    NSString *soapMessage = [NSString stringWithFormat:@"%@%@%@",soapHtmlHead,soapHtmlMiddle,soapHtmlFoot];

    
    NSLog(@"soapMessage: \n%@",soapMessage);

    //請求發送到的路徑
    NSURL *path = [NSURL URLWithString:url];
    NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:path];
/////////////////
    NSString *msgLength = [NSString stringWithFormat:@"%lu", (unsigned long)[soapMessage length]];
    [theRequest addValue:msgLength forHTTPHeaderField:@"Content-Length"];
    [theRequest addValue:@"text/xml;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    
    [theRequest addValue:soapAction forHTTPHeaderField:@"SOAPAction"];
    [theRequest setHTTPMethod:htttpMethod];
    [theRequest setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
/////////////////
    //請求
    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    //如果連接已經建好,則初始化data
    if( theConnection )
    {
        _webData = [NSMutableData data];
    }
    else
    {
        NSLog(@"theConnection is NULL");
    }
    
    return theConnection;
}
-(void)appendSoapHtmlMiddle:(NSMutableString **)soapHtmlMiddle WithParams:(NSMutableDictionary *)params
{
    for (NSString *key in params.allKeys) {
        
        [*soapHtmlMiddle appendString:[NSString stringWithFormat:@"<%@>",key]];
        
        id value = params[key];
        
        if ([value isKindOfClass:[NSDictionary class]]) {
            [self appendSoapHtmlMiddle:&*soapHtmlMiddle WithParams:value];
        }else if ([value isKindOfClass:[NSArray class]]){
            for (id oneValue in value) {
                if ([oneValue isKindOfClass:[NSDictionary class]]) {
                    [self appendSoapHtmlMiddle:&*soapHtmlMiddle WithParams:oneValue];
                }
            }
        }else{
            [*soapHtmlMiddle appendString:[NSString stringWithFormat:@"%@",value]];
        }
        
        [*soapHtmlMiddle appendString:[NSString stringWithFormat:@"</%@>",key]];
    }
}
/*
 */
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//    [webData setLength: 0];
    self.statusCode = [(NSHTTPURLResponse*)response statusCode];
//    NSLog(@"connection: didReceiveResponse:1------%@,statusCode:%ld",response,self.statusCode);

}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [_webData appendData:data];
//    NSLog(@"connection: didReceiveData:2");
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"ERROR with theConenction----:%@",error);
    if (self.resultBlock) {
        NSString *message = MyLocalizedString(@"theConenction_error", nil);
        self.resultBlock([NSNumber numberWithInteger:self.statusCode],NO,message);
    }
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//    NSLog(@"3 DONE. Received Bytes: %lu", (unsigned long)[_webData length]);
    
    NSString *st = [[NSString alloc] initWithData:_webData encoding:NSUTF8StringEncoding];
//    NSLog(@"connectionDidFinishLoading----:%@",st);

//    NSLog(@"得到的XML=%@", st);
    
    NSError *error;
     
    id resultDic = [XMLReader dictionaryForXMLString:st error:&error];
    
//    NSLog(@"result---:%@",resultDic);
    
    BOOL isDic = [resultDic isKindOfClass:[NSDictionary class]];
    NSString *message;
    if (!error) {
        if (isDic) {
            resultDic = resultDic[@"soapenv:Envelope"][@"soapenv:Body"][@"RESPONSE"];
            NSInteger statusCode = [[NSString stringWithFormat:@"%@",resultDic[@"STATUS_CODE"][@"text"]] integerValue];
            message = resultDic[@"MSG"][@"text"];
            if (!message) {
                message = resultDic[@"Msg"][@"text"];
            }
            if (statusCode != 0) {
                if (statusCode == 200) {
                    //request valid   註冊成功會返回200
                }else if (statusCode == 401){//user is not authenticated
                    resultDic = [NSNumber numberWithInteger:statusCode];
                    if (![self.soapMethodName isEqualToString:user_login_MethodName]) {//如果是在登錄界面點擊登錄
                        if (![myAppDelegate.window.rootViewController isKindOfClass:[FLLoginViewController class]]) {
                            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:MyLocalizedString(@"user_is_not_authenticated", @"登錄失效請重新登錄...") preferredStyle:UIAlertControllerStyleAlert];
                            UIAlertAction *alertAction1 = [UIAlertAction actionWithTitle:MyLocalizedString(nil, @"OK") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                                [[FLUserManager defaultUserManager] gotoLoginPage];
                            }];
                            [alertController addAction:alertAction1];
                            [myAppDelegate.window.rootViewController presentViewController:alertController animated:YES completion:NULL];
                        }
                        
                    }
                    
                }else if (statusCode == 500){//server error
                    resultDic = [NSNumber numberWithInteger:statusCode];
                }
                
            }
        }else{

            resultDic = [NSNumber numberWithInteger:110];
        }
         NSLog(@"%@ successed",self.soapMethodName);
        if (self.resultBlock) {
            self.resultBlock(resultDic,isDic,message);
        }
        
       
    }else {
        NSLog(@"解析錯誤%@",error);
        if (self.resultBlock) {
            self.resultBlock([NSNumber numberWithInteger:110],isDic,error.description);
        }
    };
    
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章