OStack程序员社区-中国程序员成长平台

标题: iOS - API 对象和 Controller 之间的通信 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 22:18
标题: iOS - API 对象和 Controller 之间的通信

我对两件事感到好奇:

1在与 API 和 View Controller 通信的对象之间设计通信的高效且易于扩展的方式是什么

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

(我知道,我在下面提到的方法很困惑,但截止日期很疯狂,直到现在我都没有时间真正考虑它。)

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

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

我的方法:

因此,与 API 的对象通信(简称​​apiComm)由所有 UIViewControllers 共享。 apiComm 有 10-15 个方法,每个方法对应 API 能够处理的方法;各个请求内容之间存在很大差异.. => 问题 2

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

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



Best Answer-推荐答案


对我来说,解决这个棘手问题的唯一真正答案或方向是:

所以,只是一些复杂的想法。最后一点 - 一切都只是转移到 parse.com 所以这一切都变得毫无意义,幸运的是

这几乎是“我正在与一个还没有搬到 bAAs 的客户合作('不,真的!')所以我如何保持网络代码整洁......!”呵呵。


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

将它放在任何需要它的应用程序中。

如今,在 iOS 中处理 JSON 非常容易。所以,我所描述的往往是微不足道的......不过是几十行代码。

您的“云”文件将包含如此简单的例程......这个单例将被称为“BLANKS”或类似的......它从服务器获取一些“空白”用户文件类型,比方说。

-(void)loadIfNeededThenvoid(^)(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)_refreshThenvoid(^)(void))after
    {
    dispatch_async(dispatch_get_main_queue(),
        ^{
        self.rawBlanksFromCloud = [NSData dataWithContentsOfURL:uBlanks];

        [self _doShowAllOnLog];

        after();
        });
    }

值得意识到的是,所有都在转移到 Parse.com 和其他 bAA。没有其他现实的 future ,今年年底之后不会有太多“服务器端”。

所以在实践中,这些简单的单例变得更加简单——它们只是连接到 Parse 的几行代码。享受吧!

所以 TBC 上面的代码示例来自“ye olde web server”的情况。

这是一个获取“用户文件”的示例..(注意方便的例程 postStringUser 用于组装该死的 url 调用..我从来没有找到一个真正巧妙的方法来做到这一点!)...

-(NSString *)postStringUserNSString *)user passNSString *)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)fetchTheUsersFilesNSString *)user passNSString *)pass thenvoid(^)(void))after
{
NSString *postString = [self postStringUser:user pass:pass];
NSLog(@"postString is %@ ", postString );

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:yourUrl];
request.HTTPMethod = @"OST";
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();
    }];

}

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

NSMutableURLRequest *request = ...

[NSURLConnection sendAsynchronousRequest: request ...

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

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

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

希望对你有帮助!

关于iOS - API 对象和 Controller 之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23801085/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4