iOS - API 对象和 Controller 之间的通信
<p><p><strong>我对两件事感到好奇:</strong></p>
<p><strong>1</strong>在与 API 和 ViewController 通信的对象之间设计通信的高效且易于扩展的方式是什么</p>
<p><strong>2</strong>如何设计通信对象本身(如何设计可扩展的方法,..)</p>
<p>(我知道,我在下面提到的方法很困惑,但截止日期很疯狂,直到现在我都没有时间真正考虑它。)</p>
<p><strong>让我介绍一下我正在处理的任务:</strong></p>
<p>根据与 API 的通信,我必须编写 2-3 个应用程序。 API 响应了大约 10-15 种不同的方法(通过 http POST 发送,结果为 JSON)。当然,通信必须是异步的。</p>
<p><strong>我的方法:</strong></p>
<p>因此,与 API 的对象通信(简称<em>apiComm</em>)由所有 UIViewControllers 共享。
<em>apiComm</em> 有 10-15 个方法,每个方法对应 API 能够处理的方法;各个请求内容之间存在很大差异.. => <strong>问题 2</strong></p>
<p>当 <em>apiComm</em> 从 API 收到数据时,它会在 上发布通知。这意味着,每个想要使用 <em>apiComm</em> 的 UIViewController 都必须为通知注册自己并实现处理传入通知的方法。由于一些 UIViewController 不得不处理更多的 API 请求,这种方法变得令人讨厌,... => <strong>问题 1</strong></p>
<p>我想知道在设计这些问题时是否可以使用通用模式..
对于这个问题的任何部分,我将不胜感激。</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>对我来说,解决这个棘手问题的唯一真正答案或方向是:</p>
<ul>
<li><p>正如@liamnichols 指出的那样,一定要使用某种类似于抽象类的模式</p></li>
<li><p>如果您正在阅读这篇 iOS 新书,使用“after...” block 模式是绝对必要的(下面代码中的示例)</p></li>
<li><p>在这一点上,这是 iOS/objective-C 中的一个绝对关键点 <a href="https://stackoverflow.com/a/20760583/294884" rel="noreferrer noopener nofollow">https://stackoverflow.com/a/20760583/294884</a> ..如何使 block 成为属性</p></li>
<li><p>纯粹是 IMO,我从来没有找到一个大项目,其中“15 个项目”实际上可以真正合理化。它只是还没有发生。所以对我们来说最好的办法是仔细 - 至少 - 包装它,以便(以一种或另一种方式)您将“15 个项目”称为这样的东西 .. CLOUD.NOTES .. CLOUD.PROFILE .. CLOUD.SCORES .. 和从你的代码的其余部分等等。</p></li>
<li><p>当然要为网络系统使用单例</p></li>
<li><p>为网络系统同时使用 KVO 和 NSNotifications 至关重要</p></li>
<li><p>值得注意的是,如今在 iOS 世界中处理 JSON 非常容易,以至于(幸运的是)“只有 15 个单独的文件”{一种或另一种方式} 确实不错很容易将其视为您可以做出的最明确的合理化。</p></li>
</ul>
<p>所以,只是一些复杂的想法。最后一点 - 一切都只是<strong>转移到 parse.com</strong> 所以这一切都变得毫无意义,幸运的是:)</p>
<p>这几乎是“我正在与一个还没有搬到 bAAs 的客户合作('不,真的!')所以我如何保持网络代码整洁......!”呵呵。</p>
<hr/>
<p>再简单不过了,<strong>写一个漂亮的单例</strong>。</p>
<p>将它放在任何需要它的应用程序中。</p>
<p>如今,在 iOS 中处理 JSON 非常容易。所以,我所描述的往往是微不足道的......不过是几十行代码。</p>
<p>您的“云”文件将包含如此简单的例程......这个单例将被称为“BLANKS”或类似的......它从服务器获取一些“空白”用户文件类型,比方说。</p>
<pre><code>-(void)loadIfNeededThen:(void(^)(void))after
{
if ( self.rawStubsFromCloud != nil )
{
NSLog(@"good new, blanks are already loaded!!");
after();
return;
}
; // (use MBProgressHUD for all spinners)
APP.hud.labelText = @"Loading file blanks from cloud...";
dispatch_after_secs_on_main(0.1 ,
^{
[self _refreshThen:
^{
;
NSLog(@"loaded the blanks fine:\n%@\n",
);
after();
}];
}
);
}
-(void)_refresh
{
;
}
#define uBlanks
-(void)_refreshThen:(void(^)(void))after
{
dispatch_async(dispatch_get_main_queue(),
^{
self.rawBlanksFromCloud = ;
;
after();
});
}
</code></pre>
<p>值得意识到的是,所有<strong>都在转移到 Parse.com 和其他 bAA</strong>。没有其他现实的 future ,今年年底之后不会有太多“服务器端”。</p>
<p>所以在实践中,这些简单的单例变得更加简单——它们只是连接到 Parse 的几行代码。享受吧!</p>
<p>所以 TBC 上面的代码示例来自“ye olde web server”的情况。</p>
<p>这是一个获取“用户文件”的示例..(注意方便的例程 postStringUser 用于组装该死的 url 调用..我从来没有找到一个真正巧妙的方法来做到这一点!)...</p>
<pre><code>-(NSString *)postStringUser:(NSString *)user pass:(NSString *)pass
{
NSString *username = user;
NSString *password = pass;
NSMutableString *r = ;
;
;
;
;
;
];
;
;
];
return r;
}
#define yourUrl
-(void)fetchTheUsersFiles:(NSString *)user pass:(NSString *)pass then:(void(^)(void))after
{
NSString *postString = ;
NSLog(@"postString is %@ ", postString );
NSMutableURLRequest *request = ;
request.HTTPMethod = @"POST";
request.HTTPBody = [ postString dataUsingEncoding:NSUTF8StringEncoding];
;
; // 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:
completionHandler:^(NSURLResponse *r, NSData *data, NSError *error)
{
;
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 )
{
;
}
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 = ;
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;
or for example...
NSDictionary *oneStubDict = self.rawArrayFromCloud;
NSString *subjectName = oneStubDict[@"subjectName"];
NSString *mainBody = oneStubDict[@"mainBody"];
NSString *authorField = oneStubDict[@"authorField"];
*/
[APP simpleOK: sayString
then:^{ ; } ];
}
if (after) after();
}];
}
</code></pre>
<p>请注意,关键代码只不过是...</p>
<pre><code>NSMutableURLRequest *request = ...
[NSURLConnection sendAsynchronousRequest: request ...
NSDictionary* jdic = [NSJSONSerialization JSONObjectWithData:result ...
NSArray *theFiles = ;
NSString *aField = theFiles["coverInfo"]["aField"];
</code></pre>
<p>希望对你有帮助!</p></p>
<p style="font-size: 20px;">关于iOS - API 对象和 Controller 之间的通信,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/23801085/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/23801085/
</a>
</p>
页:
[1]