• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

iOS - API 对象和 Controller 之间的通信

[复制链接]
菜鸟教程小白 发表于 2022-12-12 22:18:40 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我对两件事感到好奇:

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-推荐答案


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

  • 正如@liamnichols 指出的那样,一定要使用某种类似于抽象类的模式

  • 如果您正在阅读这篇 iOS 新书,使用“after...” block 模式是绝对必要的(下面代码中的示例)

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

  • 纯粹是 IMO,我从来没有找到一个大项目,其中“15 个项目”实际上可以真正合理化。它只是还没有发生。所以对我们来说最好的办法是仔细 - 至少 - 包装它,以便(以一种或另一种方式)您将“15 个项目”称为这样的东西 .. CLOUD.NOTES .. CLOUD.PROFILE .. CLOUD.SCORES .. 和从你的代码的其余部分等等。

  • 当然要为网络系统使用单例

  • 为网络系统同时使用 KVO 和 NSNotifications 至关重要

  • 值得注意的是,如今在 iOS 世界中处理 JSON 非常容易,以至于(幸运的是)“只有 15 个单独的文件”{一种或另一种方式} 确实不错很容易将其视为您可以做出的最明确的合理化。

所以,只是一些复杂的想法。最后一点 - 一切都只是转移到 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/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap