2015-04-22 43 views
0

我正在Swift中为iOS创建一个应用程序,并且试图将我的API调用逻辑保留在我的ViewControllers之外。我跟着this tutorial进行了一个API调用,我将在下面介绍。使用协议实现多个API调用(服务器请求)

我正在创建ViewController将实现的协议“APIControllerProtocol”,然后创建一个APIController类,该类将包含名为'delegate'的属性以保存APIControllerProtocol类型的实例。该协议被简单地定义为

protocol APIControllerProtocol { 
    func didReceiveAPIResults(result: SwiftyJSON.JSON) 
} 

而且视图控制器将实行didReceiveAPIResults函数的调用API调用返回JSON数据之后。 ViewController将包含一个APIController的实例,并调用一个函数调用API。

在这一点上,我想让更多的ViewControllers执行API调用,如果我只需要为每个ViewController调用1个API,那么我可以将另一个函数添加到APIController中,并且我可以让新的ViewController使用相同的协议。但是,如果有,将需要作出2所或多个API调用的ViewController这个逻辑是有缺陷的,因为

  1. 我不能在两种不同的方式调用didReceiveAPIResults在ViewController中,
  2. 我不认为添加多个'委托'属性到APIController类来保存不同类型的协议是一条路。

  3. 在协议中定义多个函数意味着我将不得不在ViewControllers中实现所有这些函数,只需要进行1次API调用即可。

我的思路来解决这个问题是

  1. 做一个APIController类APIControllerProtocol在APIControllerProtocol每个视图控制器

  2. 使用可选功能,因此不是每个视图控制器就必须实现所有的功能(我不知道这会如何工作)

任何其他见解,将不胜感激。

回答

0

您对“API”一词的使用令人困惑。这听起来像你的意思是一个服务器请求,所以这就是我要称之为。

我会建议使用完成块/封闭设计而不是基于协议的设计。

使您的网络请求类的调用取得完成关闭,并在服务器请求完成后调用该完成关闭。

您可以编写网络请求类来维护每个待处理请求的请求列表和完成关闭,并在每个请求完成或失败后调用关闭。

+0

是的,此处的API调用表示服务器请求。闭包设计对协议设计有什么好处?我不明白维护一个请求列表的重要性是什么?您能否提供代码或指向教程的链接以向我展示如何使用服务器请求的关闭? – hoffware

+0

这听起来像你想拥有一个管理多个服务器请求的类。代表是一对一的关系。每个服务器管理器对象只能有一个且只有一个委托。您不能以这种方式管理来自3个不同视图控制器的未决请求。有了完成块,你可以。 –

+0

您可能想要看看像AFNetworking这样的图书馆,而不是重新发明轮子。特别是那个非常丰富和成熟,有很多很棒的功能,并且有成千上万的开发者在使用它。它能做到我们谈论得非常好。 –

0

在协议中定义多个功能将意味着我将不得不 实现所有这些功能在ViewControllers只需要 使1个API调用。

这是不正确的。创建可选功能,你可能有你的答案。

@objc protocol APIControllerProtocol { 
    func didReceiveAPIResults(result: SwiftyJSON.JSON) 
    optional func someAwesomeMethod() 
} 

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

任择议定书要求

您可以定义协议的可选的要求,这些要求 不必由符合协议类型来实现。 可选要求以可选修饰符作为协议定义的一部分 的前缀。

可选的协议需求可以通过可选的链接调用, 用于说明需求不是由符合协议的类型实现的 。有关可选链接的信息 ,请参阅可选链接。

通过在请求名称后面写入 问号,例如someOptionalMethod?(someArgument),可以检查可选需求的实现。可选属性 要求和返回值的可选方法要求 将在访问或调用 时始终返回适当类型的可选值,以反映可选 要求可能尚未实现的事实。

+0

我得到的错误 “‘可选’只能是应用于“@ objc'协议的成员”,我认为这意味着我需要执行'@objc协议APIControllerProtocol'。但是,检查使用可选函数的UITableViewDelegate的源代码时,我注意到它没有'@ objc'标记。我必须添加'@ objc'标签吗? – hoffware

+0

在我发布的文档中对此进行了讨论。 @objc协议APIControllerProtocol –

+0

当我向协议中添加@ @ objc时,会出现另一个错误“由于无法在Objective-C中表示参数的类型,因此方法不能标记为”@ obc“。我可以返回另一个JSON表示,或者在调用委托之前解析JSON,但是还有其他选项吗? – hoffware

0

你基于你的逻辑的教程看起来对我来说不好。它所做的,它实现了一个标准的委托模式调整到最大值。 DetailsViewController有一个APIViewController实例,它将它自己指定为代理 - 非常标准。但是,然后DetailsViewController会调用该APIViewController实例上的方法以获取在DetailsViewController中实现的委托方法。这对我的口味来说太过分了。

更合理的模式是创建一个单独的(共享实例)对象,它将处理您的API调用,并且任何视图控制器都可以访问它。在那里你可以实现你的参数的方法,其中之一是一个闭包,当你的请求完成时将结果传递给视图控制器。

所以在您的视图控制器,你会打电话来是这样的:

APIController.sharedInstance.doSomethingWith(someParameter, completion: { (result) -> Void in 
    // Do something with the result 
}) 

你APIController会实现这个像这样

func doSomethingWith(param: String, completion: (AnyObject) -> Void) { 
    // do your data fetching here... 
    // pass the result to the closure when the data is retrieved 
    completion(result) 
} 
相关问题