【问题标题】:Needing a design pattern/example link for iPhone network connections需要 iPhone 网络连接的设计模式/示例链接
【发布时间】:2010-02-04 23:57:27
【问题描述】:

如果这是一个基本问题,我很抱歉。我一直在谷歌搜索、搜索 StackOverflow 并查看示例代码几个小时,但没有找到任何符合我技能水平的东西。

我想要一种类似设计模式的东西,用于在 iPhone SDK 上处理网络功能。我听说有人使用单例类,但听说有更好的异步连接方法。 NSOperation 有用吗?我对面向对象编程相当陌生,但我需要通过 HTTP 为我当前的应用程序偶尔调用我的网络服务器,并希望找到一个易于重用的解决方案。

我查看了 NSURLConnection 文档并可以获得基本功能,但编程结构很混乱,我不确定如何更好地组织它。是否有示例代码将这些函数分离到它们自己的类中?非常感谢一个指向执行此操作的示例的链接! 谢谢!

【问题讨论】:

    标签: iphone design-patterns


    【解决方案1】:

    我一直在处理同样的问题......

    1. 如果您有效地对一个简单资源执行 GET,并且您确信该资源将始终存在且可访问,那么有一种简单的方法可以做到:

      NSURL *URL=[[NSURL alloc] initWithString:@"http://www.google.com/"l];
      [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
      //TODO This needs to have timeouts & such set up, maybe parallelism
      NSString *results = [[NSString alloc] initWithContentsOfURL :URL];
      [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
      

      这是一种非常简单的方法,但正如我的评论所说,不是很健壮或可靠。

    2. 一个更健壮但仍然相当简单的方法是将 NSString 行替换为:

      results = [[NSString alloc] initWithContentsOfURL:URL encoding:NSASCIIStringEncoding error:&err]; // possibly NSUnicodeStringEncoding
      if (err!=nil) NSLog(@"Error occurred: %@", [err localizedDescription]);
      

      这至少会告诉你是否有错误......

    3. ASIHTTPRequest 提供了许多简洁实用的网络功能,用于处理 Internet 上的资源。 http://allseeing-i.com/ASIHTTPRequest/ - 开发人员在他的 Google 群组上反应非常迅速。我真的很想使用它,并且当/如果它支持 SSL 客户端证书身份验证(这是我的项目所需要的)时可能会重新使用它。

    4. NSURLConnection,如上所述 - 这就是我现在在我的项目中使用的。我想这将满足几乎所有的需求,但它(在我看来)使用起来更加棘手。老实说,我仍然在思考如何将异步数据加载集成到我的应用程序中时遇到一些麻烦。但如果它对你有用——而且很可能会,Apple 正在整个操作系统及其应用程序中使用它——那是你最好的选择!

    【讨论】:

    • 使用 initWithContentsOfURL 需要注意的一点是,它是块,并且确实创建了一个单独的线程。这样,如果网络连接很慢,那么您的应用程序可能在方法调用期间没有响应。
    【解决方案2】:

    一种可能的方法是使用NSURLConnection(如您所述)。

    在您的 .h 文件中:

    NSMutableData *connectionData;
    

    还要为 connectionData 添加一个属性...

    在您的 .m 文件中:

    - (void)updateFromServer {
        // You might want to display a loading indication here...
    
        NSMutableData *connectionDataTemp = [[NSMutableData alloc] init];
        self.connectionData = connectionDataTemp;
        [connectionDataTemp release];
    
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL: your_url];
        NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
        [connection release];
        [request release];
    }
    
    #pragma mark -
    #pragma mark NSURLConnectionDelegate
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
        // Add the received bulk of data to your mutable data object
        [self.connectionData appendData:data];
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
        // Use your data
    
        // If there is a loading indication displayed then this is a good place to hide it...
    }
    
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        // Handle error
    
        // If there is a loading indication displayed then this is a good place to hide it...
    }
    

    【讨论】:

    • 感谢您的回复。这最好放在我的 AppDelegate 中还是视图控制器中?或者我应该有一个连接类并在需要时在我的每个视图控制器类中实例化它?
    • 这取决于您的需求。如果你只在一个视图控制器中使用它,那么我肯定会把它放在那里。我肯定不会将此功能放在应用程序委托中(我尽量避免将其用作代码容器)。如果您使用来自许多视图控制器的连接事物,您可以将它放在某个外部类中,但是,通常,回调中的代码对于调用它的视图来说是私有的,因此以这种方式使用它可能会很棘手(您可能使用 showLoading、hideLoading、dataReceived 等方法实现您自己的协议。
    • 另一种可能的方法是实现一个基本视图控制器,它将实现所有这些方法(一些默认实现),您将覆盖每个具体视图控制器中的实现......
    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多