服务端重数据、客户端重展示
服务端输入的是数据,处理后输出的还是数据
客户端输入的是用户行为,处理后输出的是GUI(展示)
- 数据如何获取?
- 数据如何存储?
- 数据如何展示?
目前在大多数的iOS项目中,Model层只是一个单纯的数据结构
定义了一堆属性,只是一个简单的模板,并没有参与到实际的业务逻辑中去,只是在模型层进行了一次抽象。将服务端返回的JSON数据一一取出映射到模型里方便调用时可以直接使用数据。
所以说,模型和网络服务联系非常密切,那么网络请求应该写在模型中还是写在哪里?
大多数的应用都会将网络服务组织成单独的一层,这就是所谓的MVCS架构,就是在MVC的基础上加了一层服务层(Service),当引入Service层之后,整个数据的获取及处理是这样的:
- 大多数情况下的发起都是在Controller中进行的;
- 然后会在HTTP请求的回调中交给模型层处理json数据;
- 返回模型对象交给Controller控制器;
- 最后由View层展示服务端返回的数据;
import Foundation
import Alamofire
final class UserManager {
static let baseURL = "http://localhost:3000"
static let usersBaseURL = "\(baseURL)/users"
static func allUsers(completion: @escaping ([User]) -> ()) {
let url = "\(usersBaseURL)"
Alamofire.request(url).responseJSON { response in
if let jsons = response.result.value as? [[String: Any]] {
let users = User.users(jsons: jsons)
completion(users)
}
}
}
static func user(id: Int, completion: @escaping (User) -> ()) {
let url = "\(usersBaseURL)/\(id)"
Alamofire.request(url).responseJSON { response in
if let json = response.result.value as? [String: Any],
let user = User(json: json) {
completion(user)
}
}
}
}
UserManager.user(id: 1) { user in
self.nameLabel.text = user.name
self.emailLabel.text = user.email
self.ageLabel.text = "\(user.age)"
self.genderLabel.text = user.gender.rawValue
}
在这个方法中,完成了网络请求,数据转换json,json转模型,以及最终使用回调,返回构建好的模型对象。
模型层只有与服务层一起使用才能发挥更重要的能力。
当然也可以把网络获取资源写在model层,很多人也是这么做的,model和Service本来就联系密切,放在一起并无不妥。但我个人更推崇单独的使用Service层,我觉得各个模板的功能独立起来比较方便维护。
model层,还应该提供数据的存储功能。