영어 잘하는 개발자 쨩쨩인게 좋은 해외 아티클이 많기 때문,,
요즘 단어부터 하고 있긴한디 그냥 잘했으면ㅎㅎㅎ
'쉽게 얻는건 쉽게 잃어' - 윤성빈 선수-
참고한 글(ref) : https://medium.com/swift-india/mvvm-2-a-deep-tour-3c8d9fa0cd53
먼저 MVVM (Model, View, ModelView)에 대해 간단하게 요약하자면.
특징은 각각 독립적이며 모듈화가 가능하다.
command, data binding 패턴을 이용한다.
- 데이터 바인딩은 서로에게 데이터 변경을 알려줄 수 있는 방법이며, 대표적으로 observable가 있다.
<역할>
Model : 데이터
View : 사용자 UI, 입출력을 담당
View Model : View를 표현하기 위한 모델. 데이터를 가공하고 처리
<과정>
1. Model에서 데이터 구조화, 캡슐화
2. View에서 사용자의 액션(UI)을 받음 -> ViewModel 전달
3. ViewModel에서 Model에 데이터 요청
4. Model에서 ViewModel로 데이터 응답
5. ViewModel에서 데이터를 처리 -> View를 업데이트함 (data binding)
<프로젝트 구조 예>
(상위) Modules
(하위) Model
(하위) View
(하위) ViewModel
MVVM 단점(Disadvantages)
- MVVM for beginners is hard to put to use. (ㅠㅠㅠㅠㅠ)
- 여러 컴포넌트 사이에서의 통신과 데이터 바인딩이 어려울 수 있다.
- 중첩된 뷰 안에서 view model들과 상태를 관리하는 것과 복잡한 UI는 어렵다. (Managing view models and their state in nested views and complex UI’s is difficult.) <- 해석이 이게 맞나?ㅋㅋㅋㅠㅠㅠ
뷰의 코드 재사용성
"같은 뷰에서 여러 뷰 모델 사용하기"
Example - Model
"장소"에 대한 데이터 모델 만들기
enum PlaceType: String {
case restaurant = "restaurant"
case cafe = "cafe"
case club = "club"
static func allPlaceType() -> [PlaceType] {
return [.restaurant, .cafe, .club]
}
func iconUrl() -> String {
switch self {
case .restaurant:
return "url_1"
case .cafe:
return "url_2"
case .club:
return "url_3"
}
}
func cellTitleText() -> String {
switch self {
case .restaurant:
return "Top Restaurants nearby"
case .club:
return "Top Club nearby"
case .cafe:
return "Top Cafes nearby"
}
}
}
- enum으로 데이터 세트 정의
- 사용하기 쉽도록 함수(func) 생성
- static : 전역
struct Place {
var name: String?
var address: String?
var type: PlaceType!
var img: String?
var rating: Double?
var openStatus: Bool?
// 속성 초기화
init(attributes: [String: Any], type: PlaceType) {
self.type = type
self.address = attributes["vicinity"] as? String
self.name = attributes["name"] as? String
self.rating = attributes["rating"] as? Double
if let openingHours = attributes["opening_hours"] as? [String: Any] {
self.openStatus = openingHours["open_now"] as? Bool
}
setImage(attributes: attributes)
}
private mutating func setImage(attributes: [String: Any]) {
guard let photos = attributes["photos"] as? [[String: Any]] else {return}
guard photos.count > 0 else {return}
guard let photoRef = photos[0]["photo_ref"] as? String else {return}
self.img = "con_img_url"
}
}
- struct : 상태 및 동작을 캡슐화
- ? (옵셔널) : 속성의 값이 없을 수 있음 ex nill(=: null)
- ! (암시적 언랩핑 옵셔널) : 처음에는 nill이지만, 사용할 때는 값이 있는 경우. (안전한 상황에서 사용)
- as? : (지정 타입)으로 형변환하고, 형변환이 실패할 경우 nil을 할당
- mutating : 구조체나 열거형 내부에서 해당 인스턴스의 속성을 수정할 수 있도록 하는 키워드
- guard : guard문은 if와 다르게 조건이 false인 경우 실행 => guard (조건) else (조건이 false인 경우 실행되는 코드)
: setImage는 데이터의 유효성을 검사해 결과적으로 이미지의 url을 반환하는 함수이다.
photos라는 상수에 "photos"키에 해당하는 데이터를 할당 -> 이 값이 [String:Any] 가 아니면 함수가 종료(return)된다.
photoRef라는 상수에 photos의 첫 번째 데이터의 키가 "photo_ref"에 해당하는 값을 할당 -> 문자열이 아니면 종료된다.
여러 유효성 검사를 거친 후 self.img 속성을 설정 가능하다.
실제 기획 보면서 설계해보고 싶은데,, 아쉬운대로 기존 서비스 중인 프로젝트로 작성해봐야지
'iOS | SwiftUI' 카테고리의 다른 글
더 나은 iOS 개발자가 되기 위한 팁 (번역, 요약) (0) | 2023.11.16 |
---|---|
[상태 관리] Swift - observable, View life cycle (0) | 2023.10.24 |
[TIL] 스위프트 공식 튜토리얼 따라하기(2) - 카드 뷰(card view) 만들기 (1) | 2023.10.16 |
[TIL] 스위프트 공식 튜토리얼 따라하기(1) - 스택을 이용한 배열 (0) | 2023.10.13 |
[TIL] A Swift Tour 대충이지만 읽기 완료! (0) | 2023.09.13 |