Ios Swift模型对象是否应该调用API?

Ios Swift模型对象是否应该调用API?,ios,swift,model-view-controller,Ios,Swift,Model View Controller,我想知道我是否遵循MVC架构模式,在我的模型类中我可以调用API吗 i、 e 我不是直接在我的模型类中创建函数 允许这样做吗?或者我通过引入一些操作而不是存储数据违反了模型规则 在我的模型类中,我可以调用API吗 没有任何东西会限制你这样做,但通常这是意料之外的。从标准MVC的传统角度来看,控制器层负责这类任务 然而,为了避免“大规模视图控制器”问题,您可以应用“MVC-N”方法。实际上,它只是一个标准的MVC+网络客户端!这导致: 避免在每个视图控制器中重复网络逻辑 使视图控制器不那么“庞大

我想知道我是否遵循MVC架构模式,在我的模型类中我可以调用API吗

i、 e

我不是直接在我的模型类中创建函数

允许这样做吗?或者我通过引入一些操作而不是存储数据违反了模型规则

在我的模型类中,我可以调用API吗

没有任何东西会限制你这样做,但通常这是意料之外的。从标准MVC的传统角度来看,控制器层负责这类任务

然而,为了避免“大规模视图控制器”问题,您可以应用“MVC-N”方法。实际上,它只是一个标准的MVC+网络客户端!这导致:

  • 避免在每个视图控制器中重复网络逻辑
  • 使视图控制器不那么“庞大”
因此,它是这样的:

显然,网络处理API请求、反序列化响应(作为模型)并将其传递给视图控制器;因此,控制器不应了解模型。网络层和控制器层之间的通信通常是通过闭包实现的,有时您可能需要遵循代理的方法

回到您的案例,您将把代码细化为(伪代码):

并且,在视图控制器中:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // somewhere in the view controller, you could pass it as:
        Networking().getAPIData(url: ..., parameters: ...) { data in
            // here, you can access `data`...
        }
    }
}

当然,该逻辑也适用于任何指定的任务功能,而不仅仅是网络功能,例如获取设备照片(访问系统资源)或从磁盘写入和读取数据

在数据模型类中,我通常有init,它可以从API提供的任何内容创建模型类的实例;如果我必须使用两个API,我将有两个init方法。当然,如果我向API发送数据模型实例,这些方法会创建API所需的任何数据

因此,如果我有一个API以JSON的形式传递数据,另一个API以XML的形式传递数据,使用完全不同的名称(我通常无法控制API中的命名),我将有两个init以JSON或XML作为参数


在我看来,做网络接入是一个太远的步骤。特别是因为我经常使用包含数据的API,这些数据将由不同的模型对象表示。就像一个“库”API,它可以返回一本书、一张CD或一张DVD,调用应该产生三个不同的模型类中的一个。在这种情况下,您可能没有API调用“给我一本书”,只有“给我库中的一项”,它返回一个可能属于多个模型类之一的实例。

Yes,我认为解析api数据或在模型中使用该数据应该有效,只要它不与接口连接,或者api数据的显示方式在模型中定义。请结帐提示:如果你的项目是非常大的,你可以尝试毒蛇。谢谢!解释很清楚,很容易理解!
class DataModel {
    var data = "Some data that's a string"
}

// separating the networking logic in another class:
class Networking {
    func getAPIData(url: URL, parameters: [String: Any], response: @escaping (_ dataModel: DataModel) -> Void) {
        // ...

        // here, you should pass the returned data model:
        response(DataModel())
    }
}
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // somewhere in the view controller, you could pass it as:
        Networking().getAPIData(url: ..., parameters: ...) { data in
            // here, you can access `data`...
        }
    }
}