1

我正在尝试将图像从 iPhone 发布到网络服务。我将首先发布代码,然后解释我尝试过的所有内容:

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];
}

我认为它失败了,因为%@格式说明符需要一个对象。但我不确定。

4

2 回答 2

0

You are probably parsing an empty xml as your request is sent asynchronously and you don't wait for the response.
You should use the delegate methods
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data to concatenate the data you receive and
-(void)connectionDidFinishLoading:(NSURLConnection *)connection to start the parser.
Have a look at the NSURLConnectionDelegate protocol: https://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/NSURLConnectionDelegate

于 2012-11-14T13:34:21.647 回答
0

这是我与 Web 服务交互的方式。绝对不是唯一的做事方式,也可能不是最流行的,但高度安全且速度非常快。首先,我的网络服务是基于 POST 的。所有参数都发布到 web 服务,这使我具有跨平台独立性(我使用基于 PHP 和 .NET 的 web 服务)。我在所有 Web 服务调用中包含一个 APIKey,它维护安全性,因为只有 iOS 应用程序可以与 Web 服务通信。它还使我能够更改 APIKey 并在需要时强制用户更新到较新版本的应用程序(我还没有做过,但如果我需要使用它,它就在那里。这个类依赖并使用 AFNetworking。我使用了几个不同的库进行网络通信(包括 iOS 包含的框架),

这是我的类的接口文件:

/*
 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   
}];

如果您有任何问题,请告诉我。

于 2012-11-14T14:25:54.737 回答