SwiftUI ์์๋ ๋ทฐ์์ ์ฌ์ฉํ ๊ฐ์ ์ ์ฅํ๋ ๋ฐฉ์์ด ๊ธฐ์กด Storyboard ๋ฐฉ์๊ณผ๋ ๋ค๋ฆ ๋๋ค.
์ค๋์ ๋ทฐ ๋ฐ์ ํด๋์ค์์ ์ฌ์ฉ๊ฐ๋ฅํ
ํ๋กํผํฐ์๋ ํผ ์ธ @ObservedObject๋ฅผ ์๊ฐํ๊ณ
์์ฃผ ๊ฐ๋จํ ํํ ๋ฆฌ์ผ๋ก
์ฌ์ฉ๋ฒ์ ์ ๋ฆฌํ๋ ค๊ณ ํฉ๋๋ค
@ObservedObject๋ฅผ ์๊ธฐ ์ ์ ObservableObject์ ๋ํด์ ์์๋ณผ๊ฒ์
ObservableObject๋ Combine์ ์ํ ํ๋กํ ์ฝ์ ๋๋ค
ํด๋น ํฌ์คํ ์์ Combine์ ๋ค๋ฃจ์ง ์์ง๋ง RxSwift์ ๊ธฐ๋ฅ์ด๋ผ๊ณ ์๊ฐํ์๋ฉด ๋์
@ObservedObject๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์
ObservableObject ํ๋กํ ์ฝ์ ์ฑํํด ์ฃผ์ด์ผ ํฉ๋๋ค.
@ObservedObject๋ ํด๋น ํ๋กํผํฐ์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด
@Published ํ๋กํผํฐ ์๋ ํผ๊ฐ ์๋์ผ๋ก ๊ฐ์ ๋ณ๊ฒฝ์ ์๋ ค์ฃผ๊ณ
์ ๋ฐ์ดํธ๊ฐ ํ์ํ ๋ถ๋ถ์ UI๋ฅผ ๊ทธ๋ฆฌ๊ฒ ๋ฉ๋๋ค!
์ฐ์ api๋ฅผ ํต์ ํ๋ฉด ๋ฐ๊ฒ ๋๋ JSON ๊ตฌ์กฐ๋ฅผ struct๋ก ์์ฑํ๊ฒ ์ต๋๋ค
BoardList.swift
struct Struct: Decodable {
var data: [Board]?
}
struct Board: Decodable {
var idx: String?
var title: String?
var register_date: String?
}
์ ๊ฐ ์ฌ์ฉํ api๋ ๋์ ๋๋ฆฌ ๊ตฌ์กฐ์ data๋ผ๋ ํค๊ฐ์ผ๋ก Board๋ฅผ ๋ฆฌ์คํธ ํํ๋ก ๊ฐ์ง๊ณ ์์ด์
๊ฐ์ด ์ฌ์๋ ์๊ณ ์์ฌ์๋ ์๊ธฐ ๋๋ฌธ์ ์ต์ ๋๋ก ์ค์ ํด ์ฃผ์์ด์
์ด ๊ตฌ์กฐ๋ฅผ ์ฐธ์กฐํด์ ํ ์ด๋ธ ๋ทฐ(SwiftUI์์๋ List)์ ๋ค์ด๊ฐ ํ ํ์ ๊ทธ๋ ค๋ณด๊ฒ ์ต๋๋ค
BoardRow.swift
import SwiftUI
struct BoardRow: View {
var board: Board
var body: some View {
VStack {
Text(board.title ?? "title is null")
.foregroundColor(.blue)
.lineLimit(nil)
Spacer()
Text(board.register_date ?? "(๋ฑ๋ก์ผ ์์)")
.foregroundColor(.green)
.lineLimit(nil)
}
}
}
์์ง UI๋ฅผ ๊ทธ๋ฆฌ๋ ๊ฒ์ด ์ต์ํ์ง ์์ ์๋ง์ด์ง๋ง
List์ ๋ณด์ฌ์ง๊ธฐ์ ์ถฉ๋ถํฉ๋๋ค
๋ง์ฝ์ swift ํ์ผ์ ์์ฑํ๊ณ canvas์์ ๋ทฐ๊ฐ ๋ณด์ฌ์ง๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด
PreviewProvider๋ฅผ ์์ฑํด ์ฃผ์๋ฉด ๋ฉ๋๋ค.
struct BoardRow_Previews: PreviewProvider {
static var previews: some View {
BoardRow(board: Board(idx: nil, title: nil, register_date: nil))
}
}
์ด์ URLSession์ ์ด์ฉํด์ api ํต์ ์ ํ๋๋ก ํ๊ฒ ์ต๋๋ค
NetworkManager.swift
import SwiftUI
// 1
class NetworkManager: ObservableObject {
// 2
@Published var boardList = [Board]()
init() {
guard let url = URL(string: "api ์ฃผ์ ") else {
return
}
URLSession.shared.dataTask(with: url) { data, _, _ in
guard let data = data else {
return
}
do {
// 3
let result = try JSONDecoder().decode(Struct.self, from: data)
// 4
DispatchQueue.main.async {
self.boardList = result.data ?? [Board]()
}
} catch {
print("\(error.localizedDescription)\n\(error)")
}
}.resume()
}
}
2๋ฒ์์ @Published ํ๋กํผํฐ ์๋ ํผ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด
1๋ฒ์์ ObservableObject ํ๋กํ ์ฝ์ ์ฑํํด ์ค๋๋ค
@Published ํ๋กํผํฐ ์๋ ํผ๋ฅผ ์ด์ฉํด์ ๋ค๋ฅธ ๋ทฐ์์ ์ด ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ๊ณ
๊ฐ์ด ๋ณ๊ฒฝ๋๋ ๊ฒ์ ์๋ ค์ค ์ ์์ด์
3 ์์ ์ด์ ์ JSON ๊ตฌ์กฐ๋ฅผ sturct๋ก ๋ณ๊ฒฝํ๊ณ
4 ์์ ํต์ ์ฑ๊ณตํ ๋ฐ์ดํฐ๋ฅผ @Published ํ๋กํผํฐ ์๋ ํผ๋ก ์ง์ ๋์ด ์๋
boardList ํ๋กํผํฐ์ ๋ด์์ค๋๋ค
import SwiftUI
struct ContentView: View {
// 1
@ObservedObject var networkManager = NetworkManager()
var body: some View {
NavigationView {
// 2
List(networkManager.boardList, id: \.title) { board in
Group {
// 3
BoardRow(board: board)
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
1์์ ๋ณด์๋ฉด ObservableObject๋ฅผ ์ฑํํ NetworkManager ์ธ์คํด์ค๊ฐ
@ObservedObject ํ๋กํผํฐ ์๋ ํผ๋ก ์ง์ ๋์ด ์๋ ๊ฒ์ ์์ ์์ด์
์ด์ ์ NetworkManager ์ ์์ฑ์์์ URLSession ์ ์ด์ฉํด์ api ํต์ ์ ์ํํ๊ณ
์ฑ๊ณต์ ์ผ๋ก JSON ์ด struct๋ก ๋ณ๊ฒฝ๋์ด boardList์ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด
ContentView์์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค
2์์ networkManager์ boardList๋ก List๋ฅผ ๊ทธ๋ ค์ฃผ๊ณ
์ ์ ์ด์ ์ ๋ง๋ค์ด ๋์๋ BoardRow๋ก ์ง์ ํด ์ค๋๋ค
๋ถ๋๋ฌ์ด UI์ด์ง๋ง ๊ฒฐ๊ณผ๋ฅผ ์ฒจ๋ถํด ๋ด ๋๋ค..
์ด์ ์ ์ต์ํ๋ ์คํ ๋ฆฌ๋ณด๋์๋ ๋ฌ๋ฆฌ api ํต์ ์ด ์ฑ๊ณตํ๋ฉด
์ด๋ป๊ฒ ํ๋ฉด์ ์ ๋ฐ์ดํธ๋ฅผ ์๋ฆฌ๊ณ ๊ทธ๋ ค์ผ ํ ์ง ๊ฐ์ด ์์ค๋๋ผ๊ตฌ์
๊ทธ๋ด๋ @Published์ @ObservedObject๋ฅผ ์ฌ์ฉํด๋ณด์ธ์
์ ๋ ๋ฐฐ์ฐ๋ ๋จ๊ณ์ด๋ ํ๋ฆฌ๊ฑฐ๋ ์ถ๊ฐ๋์ด์ผ ํ ๋ถ๋ถ์ด ์๋ค๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค
'๐ iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] RIBs Architecture ๊ฐ์์ ํ ํ๋ฆฟ ์ค์ (0) | 2021.11.12 |
---|---|
[Swift] push notification ์ ๋ฆฌ (with Firebase) permission๊ณผ ํธ์ ๋ฐ์ ๋ ํธ์ถ๋๋ ํจ์ (0) | 2021.10.27 |
[iOS/swift] UINavigaitonBar tint color iOS 15 + (0) | 2021.10.21 |
[swift 5] ๋ฐฐ์ด ํ์์ ๋ฌธ์์ด ๋ง๋ค๊ธฐ (0) | 2021.07.26 |
Swift 5 beginDisablingInterfaceAutorotation Ignoring ๋๋ฒ๊น (0) | 2021.07.12 |
๋๊ธ