首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS 5 NSURLConnection -使用UI反馈建立多个连接

iOS 5 NSURLConnection -使用UI反馈建立多个连接
EN

Stack Overflow用户
提问于 2012-03-05 03:35:46
回答 1查看 2.8K关注 0票数 2

我目前正在设计一个iOS 5 iPhone应用程序,它将使用.NET RESTful Web服务来提供数据更新。当应用程序最初安装时,它将连接到WS,以JSON格式下载所有数据。此后,它将只执行更新。WS为每个表提供了一个POST方法,如GetAllTableRecords()和GetLastUpdatedTableRecords()。

我使用的是iOS 5,我已经使NSURLConnection和JSON序列化/反序列化与本机库一起正确工作。每个WS POST方法调用当前驻留在它自己的Obj类中,其中包含所有的委托方法。此外,每个类都处理本地数据存储插入和更新。

每个NSURLConnection都是异步的,所有WS调用都是从视图控制器的按钮事件中删除的。

我的问题是:

  1. 在代码封装和重用方面,这是正确的设置吗?
  2. 如何处理多个WS调用,同时通过UI通知用户?

目前有两个表可供下载。这意味着应用程序将调用WS两次以获取初始数据,并在每次刷新时再次调用。我知道,因为每个NSURLConnection都是异步的,所以连接会发出请求,但是UI将继续,而委托处理数据下载。我对GCD和NSOperation/Queue做了一些研究,但我对这两种方法都不太了解,无法编写解决方案,也不知道这是否是正确的解决方案。

任何洞察力都是最有帮助的!

编辑#1:向UI提供实时更新如何?Mint应用程序在更新事务和帐户时也会做类似的事情。他们有一个小状态栏,在请求发出时,在底部弹出。

编辑2:好的,我相信我已经取得了一些进展。我们使用的是Story,入口点是Login /Controller。当单击登录按钮时,将向webservice发出一个NSURLConnection。如果响应状态代码在connectionDidFinishLoading:(NSURLConnection *)连接中为200,则执行一个segue以转到数据同步视图。此视图的目的是初始化或更新数据库,同时向用户提供反馈。更新或初始化需要另外两个web服务调用。

这是我的DataSyncView.m

代码语言:javascript
复制
@synthesize pvStatus, lbStatus;

// pvStatus = progress indicator
// lbStatus = label

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self StartDataSync];
}

- (void)StartDataSync
{    
    [lbStatus setText:@"Syncing data..."];
    [pvStatus setProgress:0.0f];

    // TODO: Determine if database is popuplated
    [self PerformInitialSync];  

    // Next screen
    [self performSegueWithIdentifier:@"SegueFromSync" sender:self];
}

// Populates data store will data from web service
- (void)PerformInitialSync
{
    // Kicks off a series of synchronous requests
    [self DownloadAllEmployeeDataA];
}

- (void)DownloadAllDataA
{
    // Dictonary holds POST values
    NSMutableDictionary *reqDic = [NSMutableDictionary dictionary];

    // Populate POST key/value pairs
    [reqDic setObject:passWord forKey:@"Password"];
    [reqDic setObject:userName forKey:@"UserName"];

    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:reqDic options:NSJSONWritingPrettyPrinted error:&error];

    // Convert dictionary to JSON
    NSString *requestJSON = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];    

    // Declare Webservice URL, request, and return data
    NSURL *url = [[NSURL alloc] initWithString:@"http://wsurl/getalla"];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    NSData *postData = [NSData dataWithBytes:[requestJSON UTF8String] length:[requestJSON length]];

    // Build the request
    [request setHTTPMethod:@"POST"];
    [request setValue:[NSString stringWithFormat:@"%d", [postData length]] forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];
    [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
    [request setTimeoutInterval:60.0];

    NSURLResponse *response;

    [lbStatus setText:@"Downloading employee data..."];
    [pvStatus setProgress:0.1f];

    // Make the response
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    // If return data received
    if(returnData)
    {
        // Get the response and check the code
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
        int code = [httpResponse statusCode];

        // Check to make sure successful code
        if (code == 200) 
        {
            // Convert JSON objects to Core Data Entity
            // Update UIProgressView and Label

            // Call next WS call
            [self DownloadAllEmployeeDataA];
        }
    }
}

- (void)DownloadAllDataB
{                
    // Same code as above but with different URL and entity
}

我遇到的问题是: UIProgressView和标签在调用时没有更新。正如我之前说过的,我甚至不知道这是否是打这些电话的最佳方式。看起来我并没有阻塞主线程,但我可能错了。再次,我将提出一个问题:在保持UI更新进度的同时,进行多个url调用的最佳方法是什么?谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-09 02:41:12

代码语言:javascript
复制
// Make the response
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

在您的问题中,您说您提出了异步加载url请求。但是在上面的代码行中,您是在发出同步请求吗?

在代码封装和重用方面,这是正确的设置吗?

  • 从您的代码来看,您没有坚持MVC。视图控制器不应该管理加载URL连接。您可以创建一个这样做的类,并使用委托通知视图控制器是否下载了数据,等等。

如何处理多个WS调用,同时通过UI通知用户?

  • 如果您想建立并发的URL连接,那么使用NSOperation和NSOperationQueue。尽量避免GCD (参见WWDC 2010会话208 )。

我遇到的问题是: UIProgressView和标签在调用时没有更新。

  • 您正在主线程上发出同步URL请求。按照您的代码,UIProgressView不应该更新。

参考URL加载系统编程指南

我的另一条评论是你的方法名,用小写字母开始方法名。剩下的看起来很好。可可编码指南

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9561318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档