提问人:MURR 提问时间:11/14/2012 最后编辑:EmilMURR 更新时间:11/14/2012 访问量:432
通过 Web 服务将 uiimage 上传到服务器时收到 NSXMLParserErrorDomain 错误 4
Getting NSXMLParserErrorDomain error 4 while uploading uiimage to server through webservice
问:
我正在尝试将图像从 iPhone 发布到 Web 服务。我将首先发布代码,然后解释我尝试过的所有内容:
NSData *Imagedata;
Imagedata = UIImagePNGRepresentation(imagee);
strSoapMsg = [[NSString alloc] initWithFormat:
@"<?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:soap12=\"http://www.w3.org/2003/05/soap-envelope\">"
"<soap12:Body>"
"<SaveMerchantImageFromIPhone xmlns=\"http://tempuri.org/\">"
"<byteArrayImage>%@</byteArrayImage>"
"<ProfileID>%d</ProfileID>"
"</SaveMerchantImageFromIPhone>"
"</soap12:Body>"
"</soap12:Envelope>", [NSData dataWithData:Imagedata],merchantProfileID];
// strSoapMsg = [[NSString alloc] initWithFormat:@"%@,%d",Imagedata,merchantProfileID];
//---print it to the Debugger Console for verification---
NSLog(@"soapMsg..........%@",strSoapMsg);
NSString *str_url = [ NSString stringWithFormat:@"%@user.asmx",xmlWebservicesUrl];
NSURL *url = [NSURL URLWithString:str_url];
req = [NSMutableURLRequest requestWithURL:url];
//---set the headers---
NSString *msgLength = [NSString stringWithFormat:@"%d",[strSoapMsg length]];
[req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[req addValue:@"http://tempuri.org/SaveMerchantImageFromIPhone" forHTTPHeaderField:@"SOAPAction"];
[req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
//---set the HTTP method and body---
[req setHTTPMethod:@"POST"];
[req setHTTPBody: [strSoapMsg dataUsingEncoding:NSUTF8StringEncoding]];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn)
{
webSaveMerchantImageFromIphone = [[NSMutableData data] retain];
}
我认为它失败了,因为格式说明符采用了一个对象。但我不确定。%@
答:
您可能正在解析一个空的 xml,因为您的请求是异步发送的,并且您不等待响应。
您应该使用 delegate 方法来
连接您接收的数据并
启动分析器。
查看 NSURLConnectionDelegate 协议:https://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/NSURLConnectionDelegate-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
以下是我与 Web 服务的交互方式。绝对不是唯一的做事方式,可能不是最受欢迎的,但高度安全且非常快速。首先,我的 Web 服务是基于 POST 的。所有参数都 POST 到 Web 服务,这使我能够跨平台独立(我同时使用基于 PHP 和 .NET 的 Web 服务)。我在所有 Web 服务调用中都包含一个 APIKey,它保持了安全性,因为只有 iOS 应用程序才能与 Web 服务通信。它还使我能够更改该 APIKey,并在需要时强制用户更新到较新版本的应用程序(我还没有这样做,但如果我需要使用它,它就在那里。此类依赖于并使用 AFNetworking。我使用了几个不同的库进行网络通信(包括 iOS 包含的框架),并且发现 AFNetworking 对我正在做的事情非常有用和高效。
这是我的类的接口文件:
/*
NetworkClient.h
Created by LJ Wilson on 2/3/12.
Copyright (c) 2012 LJ Wilson. All rights reserved.
License:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
extern NSString * const APIKey;
@interface NetworkClient : NSObject
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
block:(void (^)(id obj))block;
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
syncRequest:(BOOL)syncRequest
block:(void (^)(id obj))block;
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
syncRequest:(BOOL)syncRequest
alertUserOnFailure:(BOOL)alertUserOnFailure
block:(void (^)(id obj))block;
+(void)processFileUploadRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
fileData:(NSData *)fileData
fileName:(NSString *)fileName
mimeType:(NSString *)mimeType
block:(void (^)(id obj))block;
+(void)handleNetworkErrorWithError:(NSError *)error;
+(void)handleNoAccessWithReason:(NSString *)reason;
@end
和实现文件:
/*
NetworkClient.m
Created by LJ Wilson on 2/3/12.
Copyright (c) 2012 LJ Wilson. All rights reserved.
License:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import "NetworkClient.h"
#import "AFHTTPClient.h"
#import "AFHTTPRequestOperation.h"
#import "SBJson.h"
NSString * const APIKey = @"YourAPIKeyGoesHereIfYouChooseToUseIt";
@implementation NetworkClient
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
block:(void (^)(id obj))block {
[self processURLRequestWithURL:url andParams:params syncRequest:NO alertUserOnFailure:NO block:^(id obj) {
block(obj);
}];
}
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
syncRequest:(BOOL)syncRequest
block:(void (^)(id obj))block {
[self processURLRequestWithURL:url andParams:params syncRequest:syncRequest alertUserOnFailure:NO block:^(id obj) {
block(obj);
}];
}
+(void)processURLRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
syncRequest:(BOOL)syncRequest
alertUserOnFailure:(BOOL)alertUserOnFailure
block:(void (^)(id obj))block {
// Default url goes here, pass in a nil to use it
if (url == nil) {
url = @"DefaultURLGoesHere";
}
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:params];
[dict setValue:APIKey forKey:@"APIKey"];
NSDictionary *newParams = [[NSDictionary alloc] initWithDictionary:dict];
NSURL *requestURL;
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:requestURL];
NSMutableURLRequest *theRequest = [httpClient requestWithMethod:@"POST" path:url parameters:newParams];
__block NSString *responseString = @"";
AFHTTPRequestOperation *_operation = [[AFHTTPRequestOperation alloc] initWithRequest:theRequest];
__weak AFHTTPRequestOperation *operation = _operation;
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
responseString = [operation responseString];
id retObj = [responseString JSONValue];
// Check for invalid response (No Access)
if ([retObj isKindOfClass:[NSDictionary class]]) {
if ([[(NSDictionary *)retObj valueForKey:@"Message"] isEqualToString:@"No Access"]) {
block(nil);
[self handleNoAccessWithReason:[(NSDictionary *)retObj valueForKey:@"Reason"]];
}
} else if ([retObj isKindOfClass:[NSArray class]]) {
if ([(NSArray *)retObj count] > 0) {
NSDictionary *dict = [(NSArray *)retObj objectAtIndex:0];
if ([[dict valueForKey:@"Message"] isEqualToString:@"No Access"]) {
block(nil);
[self handleNoAccessWithReason:[(NSDictionary *)retObj valueForKey:@"Reason"]];
}
}
}
block(retObj);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failed with error = %@", [NSString stringWithFormat:@"[Error]:%@",error]);
block(nil);
if (alertUserOnFailure) {
// Let the user know something went wrong
[self handleNetworkErrorWithError:operation.error];
}
}];
[operation start];
if (syncRequest) {
// Process the request syncronously
[operation waitUntilFinished];
}
}
#pragma mark - processFileUpload
+(void)processFileUploadRequestWithURL:(NSString *)url
andParams:(NSDictionary *)params
fileData:(NSData *)fileData
fileName:(NSString *)fileName
mimeType:(NSString *)mimeType
block:(void (^)(id obj))block {
// Default url goes here, pass in a nil to use it
if (url == nil) {
url = @"DefaultURLGoesHere";
}
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:params];
[dict setValue:APIKey forKey:@"APIKey"];
NSDictionary *newParams = [[NSDictionary alloc] initWithDictionary:dict];
AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:url]];
NSMutableURLRequest *myRequest = [client multipartFormRequestWithMethod:@"POST"
path:@""
parameters:newParams
constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
[formData appendPartWithFileData:fileData name:fileName fileName:fileName mimeType:mimeType];
}];
AFHTTPRequestOperation *_operation = [[AFHTTPRequestOperation alloc] initWithRequest:myRequest];
__weak AFHTTPRequestOperation *operation = _operation;
__block NSString *responseString = @"";
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
responseString = [operation responseString];
id retObj = [responseString JSONValue];
// Check for invalid response (No Access)
if ([retObj isKindOfClass:[NSDictionary class]]) {
if ([[(NSDictionary *)retObj valueForKey:@"Message"] isEqualToString:@"No Access"]) {
block(nil);
[self handleNoAccessWithReason:[(NSDictionary *)retObj valueForKey:@"Reason"]];
}
} else if ([retObj isKindOfClass:[NSArray class]]) {
if ([(NSArray *)retObj count] > 0) {
NSDictionary *dict = [(NSArray *)retObj objectAtIndex:0];
if ([[dict valueForKey:@"Message"] isEqualToString:@"No Access"]) {
block(nil);
[self handleNoAccessWithReason:[(NSDictionary *)retObj valueForKey:@"Reason"]];
}
}
}
block(retObj);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Failed with error = %@", [NSString stringWithFormat:@"[Error]:%@",error]);
block(nil);
}];
[operation start];
}
#pragma mark - Error and Access Handling
+(void)handleNetworkErrorWithError:(NSError *)error {
NSString *errorString = [NSString stringWithFormat:@"[Error]:%@",error];
// Standard UIAlert Syntax
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:@"Connection Error"
message:errorString
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[myAlert show];
}
+(void)handleNoAccessWithReason:(NSString *)reason {
// Standard UIAlert Syntax
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:@"No Access"
message:reason
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[myAlert show];
}
@end
还有一个示例调用:
UIImage *image = [UIImage imagedNamed@"MyImage.png"];
NSData *imageData = UIImagePNGRepresentation(image);
NSString *filename = @"MyImage.png";
params = [NSDictionary dictionaryWithObjectsAndKeys:
@"Param1Value", @"Param1Name",
fileName, @"Filename",
nil];
[NetworkClient processFileUploadRequestWithURL:nil
andParams:params
fileData:imageData
fileName:fileName
mimeType:@"image/png"
block:^(id obj) {
// Do something
}];
如果您有任何问题,请告诉我。
评论