iOS 中 HTTP 通信的架构方法和返回 JSON 的解析

发布于 2024-12-13 03:46:55 字数 1335 浏览 0 评论 0原文

大家晚上好,

我的问题更多的是工程/设计模式方法,而不是具体的技术问题。

我正在开发一个应用程序,需要与返回 JSON 对象的远程 API 进行大量交互。数据的检索、解析和利用不是问题,而且工作非常顺利。我想就此类场景的最佳设计方法获得一些指导。

我将解释到目前为止我所掌握的内容(以伪代码和声明的形式),看看您是否可以提供帮助:

  1. 实现必要的 NSURLConnection 委托方法的 HTTP Fetcher 类。我使用回调方法选择器初始化该类,以便在完成时返回到调用类

    @implementation HTTPFetcher{
        - (id)initWithUrlRequest:(NSURLRequest *)aRequest 接收者:(id)aReceiver 操作:(SEL)aReceiverAction
        {
         //设置成员变量等..
        }
    
        //所有 NSURLConnection 委托方法
    
        - (void)connectionDidFinishLoading...
        {
            [接收者执行选择器:action withObject:self];
        }
    }
    
  2. 然后我有一个 Singleton HTTPController 类用于调用 HTTPFetcher:

    - (void)postWithRequestString:(NSString *)aRequestString
    {
        [urlRequest setHTTPBody:[aRequestString dataUsingEncoding:NSUTF8StringEncoding]];
    
        fetcher = [[HTTPFetcher alloc]initWithUrlRequest:urlRequest 接收者:self 操作:@selector(receivedDataFromService:)];
        [获取器启动];
    }
    
    - (void)receivedDataFromService:(HTTPFetcher *)aFetcher{
        //处理接收到的数据并将父对象拆分成NSMutableDictionary
    }
    

现在,这种方法对于我特别给出了必须建模的单独实体的应用程序来说效果非常好(我基本上将有一个 Singleton HTTPController每个实体)。

我的问题是在哪里处理 JSON 的自定义解析。目前,我正在 ViewController 中解析需要数据的地方,但这离源太近了,需要进一步抽象,但我不确定如何抽象。

我应该在 Singleton 类中包含促进解析的方法,还是应该创建更多控制器来解析操作?

我期待您的回复,

谢谢

Good evening guys,

My question is more of an engineering/design pattern approach than specifically technical.

I am developing an app that requires lots of interaction with a remote API returning JSON objects. The retrieval, parsing and utilisation of the data is not a problem and is working very smoothly. I am wanting to get some direction on the best design approach for this sort of scenario.

I will explain what I have so far (in pseudo code and declarations) and see if you can help:

  1. A HTTP Fetcher class implementing the necessary NSURLConnection delegate methods. I initialise the class with the callback method selector like so for returning to the calling class on completion

    @implementation HTTPFetcher{
        - (id)initWithUrlRequest:(NSURLRequest *)aRequest receiver:(id)aReceiver action:(SEL)aReceiverAction
        {
         //set the member variables etc..
        }
    
        //all NSURLConnection delegate methods
    
        - (void)connectionDidFinishLoading...
        {
            [receiver performSelector:action withObject:self];
        }
    }
    
  2. I then have a Singleton HTTPController class for calling the HTTPFetcher:

    - (void)postWithRequestString:(NSString *)aRequestString
    {
        [urlRequest setHTTPBody:[aRequestString dataUsingEncoding:NSUTF8StringEncoding]];
    
        fetcher = [[HTTPFetcher alloc]initWithUrlRequest:urlRequest receiver:self action:@selector(receivedDataFromService:)];
        [fetcher start];
    }
    
    - (void)receivedDataFromService:(HTTPFetcher *)aFetcher{
        //handle the received data and split the parent object into an NSMutableDictionary
    }
    

Now this approach works fantastically well for the app I have especially given the separate entities that I have to model (I will basically have a Singleton HTTPController for each entity).

My issue is where to handle the custom parsing of the JSON. Currently, I am doing the parsing the in ViewController where the data is required but this is too close to the source and needs to be abstracted out further but I am unsure how.

Should I include the methods to facilitate the parsing within the Singleton classes or should I create further controllers for parsing actions?

I look forward to hearing from you

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无语# 2024-12-20 03:46:55

我建议您构建现有的 JSON 解析库,特别是 John Engelhart 的 JSONKit,考虑到它可以说是 iOS 上性能最高的 JSON 解析库。完全可以节省您实现自定义 JSON 解析的时间,尤其是可以节省您实现对于您的需求来说太慢的代码,然后您需要迭代地改进它,直到它变得足够快以供您使用。

对于 HTTP 请求,我知道您已经实现了该行为,但您可能想要研究 ASIHTTPRequestAFNetworking 作为享有盛誉的通用网络库因为非常坚固。注意 AFNetworking 使用上述 JSONKit 库进行 JSON 解析。


ASIHTTPRequest(我在项目中使用的库)的工作方式是使用实现协议 ASIHTTPRequestDelegate 的委托对象,您可以在使用 URL 创建请求后分配该委托对象。有一个全局网络队列,它只是一个 NSOperationQueue,用于处理异步或多个并发活动请求。

您可以为对象setDelegate:开始检查您的委托是否在不同点实现了任何方法,例如didReceiveData:requestDidFinish: > 默认情况下,但您也可以使用各个操作的方法 (setDidFinishSelector:@selector(downloadComplete:)) 设置要检查的自定义选择器路径。

例如,当 didReceiveData: 回调发生时,您可以将新接收到的数据传递到存储在 ASIJSONRequest 的包装类中的缓冲区(或使用 < code>AFNetworking,它已经封装了这一点)。当缓冲区中有一个可以正确解析的完整 JSON 对象时,您可以调用 JSONKit 来完成繁重的工作,然后可能自己向 发送另一个回调didReceiveData: 的 ASIJSONRequestDelegate,但现在数据的格式可供应用程序的其余部分读取。


使用 ASIHTTPRequest 的另一种方法是使用块。支持为请求设置完成块、接收数据时调用的块等。对于这种设计模式,您甚至不需要包装类,只需设置代码块来进行解析本身,然后将解析的任何新数据返回到其所需的目的地。

I would recommend you build on an existing JSON parsing library, in particular John Engelhart's JSONKit, considering it's arguably the highest performance JSON parsing library out there for iOS. Saves you implementing custom JSON parsing at all, but especially saves you implementing code which turns out to be too slow for your needs and then you will need to iteratively refine it until it gets fast enough for you to use.

For HTTP requests, I know you've implemented the behaviour already, but you might want to investigate ASIHTTPRequest or AFNetworking as general purpose networking libraries which have a reputation for being quite robust. Note AFNetworking uses the above JSONKit library for JSON parsing.


The way ASIHTTPRequest (the library I use in my projects) works is by using a delegate object implementing the protocol ASIHTTPRequestDelegate, which you assign after creating a request with a URL. There's a global network queue which is just an NSOperationQueue, and that handles asynchronous or multiple concurrent active requests.

You can setDelegate: for the object to start checking whether your delegate has implemented any of the methods at different points, such as didReceiveData: or requestDidFinish: by default, but you can also set a custom selector path to check by using the methods for individual operations (setDidFinishSelector:@selector(downloadComplete:)).

What you could do when, for example, the didReceiveData: callback happens, is pass the newly received data into a buffer stored in a wrapper class for an ASIJSONRequest (or use AFNetworking, which already encapsulates this). When the buffer is such that there is a complete JSON object in there which can be parsed correctly, then you call out to JSONKit to do the grunt work and then maybe send another callback yourself to an ASIJSONRequestDelegate for didReceiveData:, but now the data is in a format which is readable by the rest of your application.


Another method of using ASIHTTPRequest is with blocks. There is support for setting a completion block for a request, a block that is called when data is received, etc. For this design pattern you don't even need a wrapper class, just set the code block up to do the parsing itself and return any new data parsed to its desired destination.

不寐倦长更 2024-12-20 03:46:55

一种可能性是视图或视图控制器向模型对象询问它需要的任何状态(包括来自远程服务器的内容)。当服务器有任何新数据时,模型对象会被告知,然后它可以调用更新其内部状态所需的任何所需的数据处理例程(例如,将 plists 或 json 转换为更规范的字典格式)。

One possibility would be for the View or view controller to ask a Model object for any state that it needs (including stuff from a remote server). The Model object would be told when there was any new data from the server, and it could then call any required data munging routines required to update its internal state (converting plists or json into a more canonical dictionary format, for instance).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文