Model
데이터를 담는 그릇.
•
Encoding : 서버에 올릴 데이터의 형태로 변환
•
Decoding : struct 로 데이터 파싱
메서드를 포함해야함
Model은 View, ViewModel 계층을 전혀 신경쓰지 않아도 된다
struct User {
let uid: String
let email: String
let fullname: String
var profileImageUrl: URL?
let username: String
//struct 로 파싱하는 메서드 직접 작성해야함.
//그리고 이런 메서드는 Model 로 빼야함.
init(uid: String, dictionary: [String : AnyObject]) {
self.uid = uid
self.fullname = dictionary["fullname"] as? String ?? ""
self.email = dictionary["email"] as? String ?? ""
self.username = dictionary["username"] as? String ?? ""
if let profileImageUrlString = dictionary["profileImageUrl"] as? String {
guard let url = URL(string: profileImageUrlString) else { return }
self.profileImageUrl = url
}
}
}
Swift
복사
ViewModel
Model 을 소유하고 있는 로직들의 모음 UI관련코드와는 완벽하게 분리.
•
View의 요청에 따라 로직을 실행
•
Model의 변화에 따라 View를 refresh
struct TweetViewModel {
//model 소유
let tweet: Tweet
var user: User
init(tweet: Tweet) {
self.tweet = tweet
self.user = tweet.user
}
//MARK: - 앱의 비즈니스 로직들
var profileImageUrl: URL? {
return tweet.user.profileImageUrl
}
var timeStamp: String {
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth]
formatter.maximumUnitCount = 1
formatter.unitsStyle = .abbreviated
let now = Date()
return formatter.string(from: tweet.timestamp!, to: now) ?? ""
}
var userInfoText: NSAttributedString {
let title = NSMutableAttributedString(string: user.fullname, attributes: [.font: UIFont.boldSystemFont(ofSize: 14)])
title.append(NSAttributedString(string: " @\(user.username)・\(timeStamp)", attributes: [.font: UIFont.systemFont(ofSize: 14), .foregroundColor: UIColor.lightGray]))
return title
}
}
Swift
복사
View
앱의 UI에 대한 코드를 담고 있는 계층
•
ViewModel 의 어떤 메서드를 이용할지
•
ViewModel 로 부터 데이터를 가져와 어떻게 배치할지.