iOS-API对象与控制器之间的通信 [英] iOS - communication between API object and controllers

查看:111
本文介绍了iOS-API对象与控制器之间的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对两件事感到好奇:

1 是设计与API进行通信的对象与视图控制器之间的通信的一种有效且易于扩展的方式

1 whats the efficient and easy-to-scale way to design communication between object that communicates with API and viewcontrollers

2 如何设计通信对象本身(如何设计可扩展的方法……)

2 how to design the communicating object itself (how to design methods to be scalable,..)

(我知道我下面提到的方法很混乱,但是截止日期太疯狂了,直到现在我还没有时间去考虑.)

(My approach mention below is messy, I know, but the deadlines were crazy and until now I didn't have time to think about it really.)

让我介绍一下我正在处理的任务:

我必须编写2-3个应用程序,具体取决于与API的通信. API响应大约10-15种不同的方法(通过http POST发送,结果为JSON).当然,通信必须是异步的.

I had to write 2-3 apps depending on communication with API. There was about 10-15 different methods that the API responded to (send via http POST, result in JSON). Of course the communication had to be asynchronous.

我的方法:

因此与API(简称​​ apiComm )进行通信的对象已由所有UIViewController共享. apiComm 有10到15种方法,每种方法都是API能够处理的一种方法; => 问题2

So the object communicationg with API (apiComm for short) was shared by all the UIViewControllers. apiComm had 10-15 methods, each one for the one that API is capable to process; there was big variability between individual request contents.. => question 2

apiComm 从API接收数据时,它在[NSNotificationCenter defaultCenter]上发布了通知.这意味着,每个想要使用 apiComm 的UIViewController都必须为通知进行自我注册并实现处理传入通知的方法.由于某些UIViewController必须处理更多的API请求,因此此方法变得令人讨厌,... => 问题1

When the apiComm recieved data from API, it posted notification on [NSNotificationCenter defaultCenter]. This means, that every UIViewController that wanted to use apiComm had to register self for notifications and implement method dealing with incoming notification. This methods grew nasty as some UIViewController had to process more API requests,... => question 1

我想知道在定义这些问题时是否可以使用通用模式. 对于这个问题的任何部分,我将不胜感激.

I would like to know if there is a universal pattern to use when desining these problems.. I will be greatful for any comments about any part of this problem.

推荐答案

对我来说,我可以为这个棘手问题提供的唯一真实答案或方向是:

For me the only real answers or direction I can give to this tricky problem is:

  • 一定使用@liamnichols指出的某种类似于抽象类的模式

  • by all means use some sort of abstract class -like pattern as @liamnichols points out

如果您正在阅读iOS的新功能,则绝对必须使用"after ..."块模式(以下代码中的示例)

if you are reading this new to iOS, it's absolutely essential to use the "after..." block pattern (examples in the code below)

在这一点上,这是iOS/objective-C中的绝对关键点 https://stackoverflow.com/a /20760583/294884 ..如何使块成为属性

on that point, here's an absolutely critical point in iOS/objective-C https://stackoverflow.com/a/20760583/294884 .. how to make a block a property

纯粹是IMO,我从来没有找到一个可以真正合理化""15个项目"的大型项目.只是还没有发生.因此,对我们来说最好的办法是仔细地-至少包装它,以便(以一种方式或另一种方式)将"15个项目"称为此类.. CLOUD.NOTES .. CLOUD.PROFILE .. CLOUD.SCORES ..和其余的代码都如此.

purely IMO, i've never found a big project where the "15 items" can, in fact, be really truly rationalised. it just has not happened yet. so the best for us it to carefully - at least - package it so that (one way or another) you call the "15 items" something like this .. CLOUD.NOTES .. CLOUD.PROFILE .. CLOUD.SCORES .. and so on from the rest of your code.

对于网络系统当然要使用单例

use a singleton(s) of course for the networking systems

同时获取网络系统的KVO和NSNotifications至关重要

it's critical to get with both KVO and NSNotifications for networking systems

非常重要的一点是要注意,如今,在iOS领域中处理JSON非常简单,以至于(幸运地)仅15个单独的文件"(一种或另一种)确实不错事情,并且很容易将其视为您可以做出的最明确的合理化.

it's very important to note that it is so absurdly easy to handle JSON in the iOS universe, these days, that (fortunately) having "just 15 separate files" {one way or another} is really not a bad thing and it would be easy to see it as, really, about the most definitive rationalisation you can make.

所以,只是一些混杂的想法.最后一点-一切都正在迁移到parse.com ,因此,幸运的是,所有这些都变得毫无意义:)

So, just some mixed thoughts. One final point - everything's just moving to parse.com so this all becomes moot, fortunately :)

几乎是一种情况:我正在与一个尚未搬进bAA的客户合作('不,真的!'),所以我如何保持网络代码整洁……!"嘿.

It's almost a case of "I'm working with a client who hans't yet moved to a bAAs ('no, really!') so how do I keep networking code tidy ...!" Heh.

再简单不过了,只需写一个漂亮的单例.

将其拖放到任何需要它的应用程序中.

Drop it in any app that needs it.

这些天来,在iOS中处理JSON真是难以置信.因此,我所描述的通常是琐碎的..仅仅几十行代码.

It's unbelievably easy to handle JSON in iOS these days. So, what I describe is often trivial .. little more than a few dozen lines of code.

您的云"文件将包含这样简单的例程……这个单例将被称为空白"或类似名称……让我们从服务器获取一些空白"用户文件类型.

Your "cloud" files will contain routines this simple ... this singleton would be called "BLANKS" or similar... it gets some "blank" user file types from the server, let's say.

-(void)loadIfNeededThen:(void(^)(void))after
    {
    if ( self.rawStubsFromCloud != nil )
        {
        NSLog(@"good new, blanks are already loaded!!");
        after();
        return;
        }

    [APP huddie]; // (use MBProgressHUD for all spinners)
    APP.hud.labelText = @"Loading file blanks from cloud...";

    dispatch_after_secs_on_main(0.1 ,
            ^{
            [self _refreshThen:
                ^{
                [APP.hud hide:YES];

                NSLog(@"loaded the blanks fine:\n%@\n",
                    [self supplyDisplayStyleString] );

                after();
                }];
            }
        );
    }
-(void)_refresh
    {
    [self _refreshThen:nil];
    }

#define uBlanks [NSURL URLWithString:@"http://blah.com/json/blanks"]
-(void)_refreshThen:(void(^)(void))after
    {
    dispatch_async(dispatch_get_main_queue(),
        ^{
        self.rawBlanksFromCloud = [NSData dataWithContentsOfURL:uBlanks];

        [self _doShowAllOnLog];

        after();
        });
    }

值得意识到的是,所有内容都已转移到Parse.com和其他bAA .没有其他现实的未来,到今年年底以后,服务器端"就不会有太多了.

It's worth realising that, everything is moving to Parse.com and other bAAs. There's no other realistic future, there's not going to be much "server side" after the end of this year.

因此,在实践中,这些简单的单例变得更加简单-它们只是连接到Parse的几行代码.享受吧!

So in practice, these simple singletons become even simpler - they're just the few lines of code to hook up to Parse. Enjoy!

因此,TBC的上述代码示例来自老式网络服务器"情况.

So TBC the above code sample is from an "ye olde web server" situation.

这里是获取用户文件"的示例..(请注意方便的例程postStringUser,用于组装该死的url调用..我从来没有找到一种真正整洁的方式来做到这一点!)...

Here's an example of getting "user files" .. (note the handy routine postStringUser for assembling damned url calls .. I've never found a really neat way to do that!)...

-(NSString *)postStringUser:(NSString *)user pass:(NSString *)pass
{
NSString *username = user;
NSString *password = pass;

NSMutableString *r = [NSMutableString stringWithString:@""];

[r appendString:@"command=commandExampleGetFile"];
[r appendString:@"&"];

[r appendString:@"name=blah"];
[r appendString:@"&"];

[r appendString:@"user="];
[r appendString: [username stringByUrlEncoding] ];
[r appendString:@"&"];

[r appendString:@"password="];
[r appendString: [password stringByUrlEncoding] ];

return r;
}

#define yourUrl [NSURL URLWithString:@"http://blah.com/json/blah"]

-(void)fetchTheUsersFiles:(NSString *)user pass:(NSString *)pass then:(void(^)(void))after
{
NSString *postString = [self postStringUser:user pass:pass];
NSLog(@"postString is %@ ", postString );

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:yourUrl];
request.HTTPMethod = @"POST";
request.HTTPBody = [ postString dataUsingEncoding:NSUTF8StringEncoding];
[request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField: @"Content-Type"];

[APP huddie]; // use MBProgress everywhere and always at all times in all apps always
APP.hud.labelText = @"Connecting to the cloud...";

// 1 get the data
// 2 make it a jdic
// 3 make it an array of the "files"

[NSURLConnection
  sendAsynchronousRequest: request
  queue: [NSOperationQueue mainQueue]
  completionHandler:^(NSURLResponse *r, NSData *data, NSError *error)
    {
    [APP.hud hide:YES];
    NSLog(@"Done... %@", r);

    self.rawGetFilesFromCloud = data;

    NSError* err;
    NSDictionary* jdic = [NSJSONSerialization
      JSONObjectWithData:self.rawGetFilesFromCloud
      options:kNilOptions
      error:&err];

      //dev only
      NSLog(@"Here's the whole damned jdic, for GetFiles\n%@", jdic);

    if ( ! jdic )
      {
      [APP simpleOK:@"Wrong username or pass? Or no files found."];
      }
    else
      {
      // the user has "logged in" so something like
      STATE.currentUsername = user;
      STATE.currentPassword = pass;
      // naturally you have a STATE singleton, every app needs one

      self.rawArrayFromCloud = [jdic objectForKey:@"data"];

      NSInteger kUserFiles = self.rawArrayFromCloud.count;
      NSString *sayString = [NSString stringWithFormat:
        @"We found %lu files of yours on the damned cloud.", kUserFiles];

      /*
      and for example...
      STATE.fileZero = self.rawArrayFromCloud[0];
      or for example...
      NSDictionary *oneStubDict = self.rawArrayFromCloud[17];
      NSString *subjectName = oneStubDict[@"subjectName"];
      NSString *mainBody = oneStubDict[@"mainBody"];
      NSString *authorField = oneStubDict[@"authorField"];
      */

      [APP simpleOK: sayString
          then:^{ [STATE showFileInterface]; } ];
      }

    if (after) after();
    }];

}

请注意,关键代码只不过是...

Note the critical code is little more than ...

NSMutableURLRequest *request = ...

[NSURLConnection sendAsynchronousRequest: request ...

NSDictionary* jdic = [NSJSONSerialization JSONObjectWithData:result ...

NSArray *theFiles = [jdic objectForKey:@"theFiles"];

NSString *aField = theFiles[13]["coverInfo"]["aField"];

希望有帮助!

这篇关于iOS-API对象与控制器之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆