English 中文(简体)
如何从客观的网络服务(iPhone)中接收数据?
原标题:How to return data gotten from a web service in objective- c (iPhone)?

这可能是一个 question问题。 如果有的话,则会问。

但是,在开展一个耗用网络服务的项目时,不胜枚举。 我可以与网络服务连接,获得我所需要的数据。

我希望有一个方法,把从网络服务处获得的这种数据反馈给打电话者。 唯一的问题是,数据只能从联通达尼西群岛脱盲法中获取,我无法从我的手法获得这一数据。

我的法典就是此部法典。

- (NSData *) dataForMethod:(NSString *)webMethod withPostString:(NSString *)postString
{
    NSURL *url = [NSURL URLWithString:[SigameWebServiceAddress stringByAppendingFormat:@"%@%@", @"/", webMethod]];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    NSString *msgLength = [NSString stringWithFormat:@"%d", [postString length]];

    [req addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"];
    [req setHTTPMethod:@"POST"];
    [req setHTTPBody: [postString dataUsingEncoding:NSUTF8StringEncoding]];

    conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    if (conn) 
    {
        webData = [NSMutableData data];
    }   

    // I WOULD LIKE TO RETURN WEBDATA TO THE CALLER HERE, BUT WEBDATA IS EMPTY NOW, THE  
    //connectionDidFinishLoading ONLY GETS CALLED WITH THE DATA I WANT AFTER THE COMPILER
    //IS DONE EXECUTING MY METHOD.
}

-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *) response 
{
    [webData setLength: 0];
}

-(void) connection:(NSURLConnection *) connection didReceiveData:(NSData *) data 
{
    [webData appendData:data];
}

-(void) connection:(NSURLConnection *) connection didFailWithError:(NSError *) error 
{
    NSLog(@"FATAL ERROR");
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection 
{
    NSLog(@"DONE. Received Bytes: %d", [webData length]);

    NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];

    //---shows the XML---
    NSLog(@"%@", theXML);  //NOW, THIS IS THE DATA I WANT. BUT HOW CAN I RETURN THIS TO 
                           //THE CALLER. I MEAN, THE CALLER THAT CALLED MY METHOD 
                           //+ (NSData *) dataForMethod: withPostString:
}

Any help here is appreciated! Thanks

最佳回答

实现这一点确实有 2<>m>。

  1. Create a delegate interface
  2. Use Blocks

我强烈建议不要使用同步方法——除非你/自己在周围建立了自己的同步框架(即你正在手工地开始另一条路面,并在此线上执行你的同步要求)。 从长远来看,你们会认识到,你们需要成为一席之地,你们必须重新工作一切照样。

2. 迅速概述我提出的两项选择:

1. Create a delegate interface

这里的想法是建立一个履行这一请求的班级,并制定一项议定书,即:eters/em> 必须执行。 如申请完成,你将使用代表特定方法提供数据:

议定书可以这样考虑:

@protocol RequestClassDelegate <NSObject>

- (void)requestCompleted:(ResponseClass *)data;
- (void)requestError:(NSError *)error;

@end

提出这一请求的类别可能看起来如此:

@interface RequestClass : NSObject

- (void)makeRequest:(id<RequestClassDelegate>)delegate;

@end

除您的联系逻辑外,请求类执行还可包含下列内容:

@implementation RequestClass
{
    __weak id<RequestClassDelegate> _delegate;
}

// Connection Logic, etc.

- (void)makeRequest:(id<RequestClassDelegate>)delegate
{
    _delegate = delegate;
    // Initiate the request...
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection 
{
    NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];

    // Processing, etc.

    // Here we ll call the delegate with the result:
    [_delegate requestCompleted:theResult];
}

@end

2. Use Blocks

这一解决办法与第一个解决办法大体相同,但我认为,这种解决办法比以前更合适。 在此,我们修改了<代码>RequestClas,以使用区块而不是代表:

typedef void (^requestCompletedBlock)(id);
typedef void (^requestErrorBlock)(NSError *);
@interface RequestClass : NSObject

@property (nonatomic, copy) requestCompletedBlock completed;
@property (nonatomic, copy) requestErrorBlock errored;

- (void)makeRequest:(requestCompletedBlock)completed error:(requestErrorBlock)error;

@end

而执行这一规定可能看起来如此:

@implementation RequestClass

@synthesize completed = _completed;
@synthesize errored = _errored;

// Connection Logic, etc.

- (void)makeRequest:(requestCompletedBlock)completed error:(requestErrorBlock)error
{
    self.completed = completed;
    self.errored = error;
    // Initiate the request...
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection 
{
    NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];

    // Processing, etc.

    // Here we ll call the delegate with the result:
    self.completed(theResult);
}

@end
问题回答

如同你一样,你试图从你的方法中仓促地利用数据回来,但你正在使用一种同步的方法(使用NSURonnection,并大概称其开端方法)来开始检索数据。 如果你真的想要你的方法回去,那就会 read忙地阅读。 但是,正如@Steve在另一个答复中所说的那样,你也可以重新考虑你的接口设计,而采用不同步的做法加以实施,并用他的建议处理代表或基于集团的接口。

如果你想用你的方法仓促地将数据退回,则使用同步的请求。 因此,改变贵国法典的这一部分:

conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
[conn start]; // I presume you have this somewhere
if (conn) 
{
    webData = [NSMutableData data];
} 

更像这一点:

 NSURLResponse *response = nil;
 NSError *error = nil;
 webdata = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
 if (webdata) {
     return webdata;
 }
 else {
     // Handle error by looking at response and/or error values
     return nil;
 }

如果你采用这种做法,你将不再需要你的任何代表守则。 不过,你在某些方面受到限制。 例如,如果贵国的网络服务要求通过“URL”参数以外的手段进行认证,那么你就能够使用这种方法。

Steve的回答是巨大的,我只能建议使用区块的方式。 实际上,由于我是新加入目标C,我采用了概述的办法。 它完美运作。

The Post for more details and my own point of view you can find here: http://kerkermeister.net/how-to-build-an-cocos2d-ios-app-communicating-with-a-restful-api-the-sequence/

The Post contains all the tiny steps you need to follow to get Steve s solution approach with blocks working. That includes: - an updateable view that will render information as soon as retrieved from Web API asynchronously - a controller invoking the HTTP request to the Web API - the actual HttpRequest class that uses iOS standard NSURLConnections - a model class that uses blocks as callbacks to update its data

Your going to have to either implement a separate method in which you use the data once the data has been returned by the connectionDidFinishLoading method or make the request synchronously. The reason I believe the above does not work is because the request is happening on a separate thread, so the main thread continues, but does not actually have the data.

This is a good way to do that if synchronous is what you want:

所有NSURLConnections的连接都是同步的? iOs

Your going to need to parse the XML that comes back. There are some good Objective C XML parsers out there. One in particular is made for ease of use....

它为摘取你想要的XML的价值观提供了非常轻的权重。 我用了很多次,取得了巨大成功,而且没有什么 has。 这里是我如何查询网络地址并把它变成数据。

 NSString *query = [NSString stringWithFormat:@"http://WEB_ADDRESS_FOR_XML];
    NSURL *URL = [NSURL URLWithString:query];
    NSData *data = [NSData dataWithContentsOfURL:URL];

或者与NSURLConnection一样,确实收到数据:

-(void) connection:(NSURLConnection *) connection didReceiveData:(NSData *) data 
{
    //USE THE DATA RETURNED HERE....
}

接着,从我的联系中利用Parser来获取内容:

 SMXMLDocument *document = [SMXMLDocument documentWithData:data error:NULL];

    NSLog("
XML Returned:%@",document);




相关问题
List Contents of Directory in a UITableView

I am trying to list the contents of Ringtones directory in a TableView, however, I am only getting the last file in the directory in ALL cells, instead of file per cell. This is my code: - (...

iPhone NSUserDefaults persistance difficulty

In my app i have a bunch of data i store in the NSUserdefaults. This information consists of an NSObject (Object1) with NSStrings and NSNumbers and also 2 instances of yet another object (Object2). ...

Writing a masked image to disk as a PNG file

Basically I m downloading images off of a webserver and then caching them to the disk, but before I do so I want to mask them. I m using the masking code everyone seems to point at which can be found ...

Resize UIImage with aspect ratio?

I m using this code to resize an image on the iPhone: CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0); UIGraphicsBeginImageContext(screenRect.size); [value drawInRect:screenRect blendMode:...

Allowing interaction with a UIView under another UIView

Is there a simple way of allowing interaction with a button in a UIView that lies under another UIView - where there are no actual objects from the top UIView on top of the button? For instance, ...