SwiftUI+URLSession+Combine에서 API를 두드려 보았습니다.
15978 단어 URLSessionSwiftSwiftUICombine
소개
취미로 Swift를 쓰고 있는 @KaitoKudou 입니다.
지금까지 SwiftUI는 학습한 적이 없어, 어쩐지 해보려고 생각해, SwiftUI를 사용해 외부 API를 두드려 보려고 했습니다. 어차피라면 해본 적 없는 Combine 프레임워크도 조금 걸어 보았습니다. (조금만)
데모 앱 개요
이번에는 Connpass API을 사용하여 List에서 이벤트를 표시하는 간단한 데모 앱을 만들었습니다.
먼저 완성판을 보여드리겠습니다.
이번에 만든 프로젝트는 GitHub로 올리고 있습니다.
htps : // 기주 b. 코 m / 카이 토쿠 도 / 슈 f 츠 _ 코 m 비네
모델 정의
응답을 보면서 모델을 작성합니다.
import Foundation
struct ConnpassGeneral: Codable {
let events: [Event]
}
struct Event: Codable, Hashable, Identifiable {
let id: Int
let title: String
let eventUrl: String
enum CodingKeys: String, CodingKey {
case id = "event_id"
case title = "title"
case eventUrl = "event_url"
}
}
통신부
import Combine
import Foundation
class ConnpassTopViewModel: ObservableObject {
var disposable = Set<AnyCancellable>()
@Published var connpassGeneral: ConnpassGeneral?
@Published var eventData: [Event]?
init() {
fetchConpassEvents()
}
func fetchConpassEvents() {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let url = URL(string: "https://connpass.com/api/v1/event/?keyword=Swift&order=3")!
let request = URLRequest(url: url)
URLSession.shared.dataTaskPublisher(for: request)
.map({ (data, response) in
return data
})
.decode(type: ConnpassGeneral.self, decoder: decoder)
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("error : " + error.localizedDescription)
case .finished:
print("----------success-----------")
}
}, receiveValue: { [weak self] connpassGeneral in
self?.eventData = connpassGeneral.events
print(self?.eventData as Any)
})
.store(in: &disposable)
}
}
List 부분
UIKit에서 말하는 UITableView에 해당하는 부분입니다.
import SwiftUI
struct ConnpassTopView: View {
@ObservedObject var connpassTopViewModel = ConnpassTopViewModel()
var body: some View {
NavigationView {
List(connpassTopViewModel.eventData ?? [Event.init(id: 0, title: "hoge", eventUrl: "hoge")]) { event in
NavigationLink(
destination: ConnpassEventDetailView(eventData: event)) {
ConnpassEventRowView(eventData: event)
}
}
.navigationTitle("Connpassイベント")
}
.onAppear(perform: {
self.connpassTopViewModel.fetchConpassEvents()
})
}
}
struct ConnpassTopView_Previews: PreviewProvider {
static var previews: some View {
ConnpassTopView(connpassTopViewModel: ConnpassTopViewModel())
}
}
셀을 눌렀을 때 전환 대상
이번에는 셀을 누르면 SFSafariViewController를 사용하여 Safari로 전환하도록했습니다. 그러나 SFSafariViewController는 UIKit에서 사용할 수있는 클래스입니다. SwiftUI의 View에서 UIKit을 사용하려면 UIViewControllerRepresentable 프로토콜을 준수하면 사용할 수 있습니다.
UIViewControllerRepresentable 프로토콜에서는 makeUIViewController(context:)와 updateUIViewController(_:context:)가 필수 메서드입니다.
import SafariServices
import SwiftUI
struct ConnpassEventDetailView: UIViewControllerRepresentable {
var eventData: Event
typealias UIViewControllerType = SFSafariViewController
func makeUIViewController(context: Context) -> SFSafariViewController {
let url = URL(string: eventData.eventUrl)
return SFSafariViewController(url: url!)
}
func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {
}
}
struct ConnpassEventDetailView_Previews: PreviewProvider {
static var eventData = ConnpassTopViewModel().eventData
static var previews: some View {
ConnpassEventDetailView(eventData: eventData?[0] ?? Event.init(id: 0, title: "hoge", eventUrl: "hoge"))
}
}
마지막으로
전체적으로 적은 코드 양으로 끝났습니다. SwiftUI는 UIKit에 비해 기술량이 줄어들기 쉽다고 생각했습니다. 아직 나는 UIKit 쪽이 구현에 걸리는 시간이 짧습니다만, SwiftUI에 익숙해지면 개발이 폭속으로 진행된다고 생각했습니다. Combine에 관해서는 아직 지식이 부족하기 때문에 정진합니다 ...
기존의 라이브러리도 SwiftUI에 대응한 것은 적고, 아직 잠시는 UIKit를 사용한 개발이 주류일까라고 생각했습니다.
Reference
이 문제에 관하여(SwiftUI+URLSession+Combine에서 API를 두드려 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/KaitoKudou/items/dc89a25bc2cd74449aa6
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
이번에는 Connpass API을 사용하여 List에서 이벤트를 표시하는 간단한 데모 앱을 만들었습니다.
먼저 완성판을 보여드리겠습니다.
이번에 만든 프로젝트는 GitHub로 올리고 있습니다.
htps : // 기주 b. 코 m / 카이 토쿠 도 / 슈 f 츠 _ 코 m 비네
모델 정의
응답을 보면서 모델을 작성합니다.
import Foundation
struct ConnpassGeneral: Codable {
let events: [Event]
}
struct Event: Codable, Hashable, Identifiable {
let id: Int
let title: String
let eventUrl: String
enum CodingKeys: String, CodingKey {
case id = "event_id"
case title = "title"
case eventUrl = "event_url"
}
}
통신부
import Combine
import Foundation
class ConnpassTopViewModel: ObservableObject {
var disposable = Set<AnyCancellable>()
@Published var connpassGeneral: ConnpassGeneral?
@Published var eventData: [Event]?
init() {
fetchConpassEvents()
}
func fetchConpassEvents() {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let url = URL(string: "https://connpass.com/api/v1/event/?keyword=Swift&order=3")!
let request = URLRequest(url: url)
URLSession.shared.dataTaskPublisher(for: request)
.map({ (data, response) in
return data
})
.decode(type: ConnpassGeneral.self, decoder: decoder)
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("error : " + error.localizedDescription)
case .finished:
print("----------success-----------")
}
}, receiveValue: { [weak self] connpassGeneral in
self?.eventData = connpassGeneral.events
print(self?.eventData as Any)
})
.store(in: &disposable)
}
}
List 부분
UIKit에서 말하는 UITableView에 해당하는 부분입니다.
import SwiftUI
struct ConnpassTopView: View {
@ObservedObject var connpassTopViewModel = ConnpassTopViewModel()
var body: some View {
NavigationView {
List(connpassTopViewModel.eventData ?? [Event.init(id: 0, title: "hoge", eventUrl: "hoge")]) { event in
NavigationLink(
destination: ConnpassEventDetailView(eventData: event)) {
ConnpassEventRowView(eventData: event)
}
}
.navigationTitle("Connpassイベント")
}
.onAppear(perform: {
self.connpassTopViewModel.fetchConpassEvents()
})
}
}
struct ConnpassTopView_Previews: PreviewProvider {
static var previews: some View {
ConnpassTopView(connpassTopViewModel: ConnpassTopViewModel())
}
}
셀을 눌렀을 때 전환 대상
이번에는 셀을 누르면 SFSafariViewController를 사용하여 Safari로 전환하도록했습니다. 그러나 SFSafariViewController는 UIKit에서 사용할 수있는 클래스입니다. SwiftUI의 View에서 UIKit을 사용하려면 UIViewControllerRepresentable 프로토콜을 준수하면 사용할 수 있습니다.
UIViewControllerRepresentable 프로토콜에서는 makeUIViewController(context:)와 updateUIViewController(_:context:)가 필수 메서드입니다.
import SafariServices
import SwiftUI
struct ConnpassEventDetailView: UIViewControllerRepresentable {
var eventData: Event
typealias UIViewControllerType = SFSafariViewController
func makeUIViewController(context: Context) -> SFSafariViewController {
let url = URL(string: eventData.eventUrl)
return SFSafariViewController(url: url!)
}
func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {
}
}
struct ConnpassEventDetailView_Previews: PreviewProvider {
static var eventData = ConnpassTopViewModel().eventData
static var previews: some View {
ConnpassEventDetailView(eventData: eventData?[0] ?? Event.init(id: 0, title: "hoge", eventUrl: "hoge"))
}
}
마지막으로
전체적으로 적은 코드 양으로 끝났습니다. SwiftUI는 UIKit에 비해 기술량이 줄어들기 쉽다고 생각했습니다. 아직 나는 UIKit 쪽이 구현에 걸리는 시간이 짧습니다만, SwiftUI에 익숙해지면 개발이 폭속으로 진행된다고 생각했습니다. Combine에 관해서는 아직 지식이 부족하기 때문에 정진합니다 ...
기존의 라이브러리도 SwiftUI에 대응한 것은 적고, 아직 잠시는 UIKit를 사용한 개발이 주류일까라고 생각했습니다.
Reference
이 문제에 관하여(SwiftUI+URLSession+Combine에서 API를 두드려 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/KaitoKudou/items/dc89a25bc2cd74449aa6
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import Foundation
struct ConnpassGeneral: Codable {
let events: [Event]
}
struct Event: Codable, Hashable, Identifiable {
let id: Int
let title: String
let eventUrl: String
enum CodingKeys: String, CodingKey {
case id = "event_id"
case title = "title"
case eventUrl = "event_url"
}
}
import Combine
import Foundation
class ConnpassTopViewModel: ObservableObject {
var disposable = Set<AnyCancellable>()
@Published var connpassGeneral: ConnpassGeneral?
@Published var eventData: [Event]?
init() {
fetchConpassEvents()
}
func fetchConpassEvents() {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let url = URL(string: "https://connpass.com/api/v1/event/?keyword=Swift&order=3")!
let request = URLRequest(url: url)
URLSession.shared.dataTaskPublisher(for: request)
.map({ (data, response) in
return data
})
.decode(type: ConnpassGeneral.self, decoder: decoder)
.receive(on: DispatchQueue.main)
.sink(receiveCompletion: { completion in
switch completion {
case .failure(let error):
print("error : " + error.localizedDescription)
case .finished:
print("----------success-----------")
}
}, receiveValue: { [weak self] connpassGeneral in
self?.eventData = connpassGeneral.events
print(self?.eventData as Any)
})
.store(in: &disposable)
}
}
List 부분
UIKit에서 말하는 UITableView에 해당하는 부분입니다.
import SwiftUI
struct ConnpassTopView: View {
@ObservedObject var connpassTopViewModel = ConnpassTopViewModel()
var body: some View {
NavigationView {
List(connpassTopViewModel.eventData ?? [Event.init(id: 0, title: "hoge", eventUrl: "hoge")]) { event in
NavigationLink(
destination: ConnpassEventDetailView(eventData: event)) {
ConnpassEventRowView(eventData: event)
}
}
.navigationTitle("Connpassイベント")
}
.onAppear(perform: {
self.connpassTopViewModel.fetchConpassEvents()
})
}
}
struct ConnpassTopView_Previews: PreviewProvider {
static var previews: some View {
ConnpassTopView(connpassTopViewModel: ConnpassTopViewModel())
}
}
셀을 눌렀을 때 전환 대상
이번에는 셀을 누르면 SFSafariViewController를 사용하여 Safari로 전환하도록했습니다. 그러나 SFSafariViewController는 UIKit에서 사용할 수있는 클래스입니다. SwiftUI의 View에서 UIKit을 사용하려면 UIViewControllerRepresentable 프로토콜을 준수하면 사용할 수 있습니다.
UIViewControllerRepresentable 프로토콜에서는 makeUIViewController(context:)와 updateUIViewController(_:context:)가 필수 메서드입니다.
import SafariServices
import SwiftUI
struct ConnpassEventDetailView: UIViewControllerRepresentable {
var eventData: Event
typealias UIViewControllerType = SFSafariViewController
func makeUIViewController(context: Context) -> SFSafariViewController {
let url = URL(string: eventData.eventUrl)
return SFSafariViewController(url: url!)
}
func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {
}
}
struct ConnpassEventDetailView_Previews: PreviewProvider {
static var eventData = ConnpassTopViewModel().eventData
static var previews: some View {
ConnpassEventDetailView(eventData: eventData?[0] ?? Event.init(id: 0, title: "hoge", eventUrl: "hoge"))
}
}
마지막으로
전체적으로 적은 코드 양으로 끝났습니다. SwiftUI는 UIKit에 비해 기술량이 줄어들기 쉽다고 생각했습니다. 아직 나는 UIKit 쪽이 구현에 걸리는 시간이 짧습니다만, SwiftUI에 익숙해지면 개발이 폭속으로 진행된다고 생각했습니다. Combine에 관해서는 아직 지식이 부족하기 때문에 정진합니다 ...
기존의 라이브러리도 SwiftUI에 대응한 것은 적고, 아직 잠시는 UIKit를 사용한 개발이 주류일까라고 생각했습니다.
Reference
이 문제에 관하여(SwiftUI+URLSession+Combine에서 API를 두드려 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/KaitoKudou/items/dc89a25bc2cd74449aa6
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import SwiftUI
struct ConnpassTopView: View {
@ObservedObject var connpassTopViewModel = ConnpassTopViewModel()
var body: some View {
NavigationView {
List(connpassTopViewModel.eventData ?? [Event.init(id: 0, title: "hoge", eventUrl: "hoge")]) { event in
NavigationLink(
destination: ConnpassEventDetailView(eventData: event)) {
ConnpassEventRowView(eventData: event)
}
}
.navigationTitle("Connpassイベント")
}
.onAppear(perform: {
self.connpassTopViewModel.fetchConpassEvents()
})
}
}
struct ConnpassTopView_Previews: PreviewProvider {
static var previews: some View {
ConnpassTopView(connpassTopViewModel: ConnpassTopViewModel())
}
}
이번에는 셀을 누르면 SFSafariViewController를 사용하여 Safari로 전환하도록했습니다. 그러나 SFSafariViewController는 UIKit에서 사용할 수있는 클래스입니다. SwiftUI의 View에서 UIKit을 사용하려면 UIViewControllerRepresentable 프로토콜을 준수하면 사용할 수 있습니다.
UIViewControllerRepresentable 프로토콜에서는 makeUIViewController(context:)와 updateUIViewController(_:context:)가 필수 메서드입니다.
import SafariServices
import SwiftUI
struct ConnpassEventDetailView: UIViewControllerRepresentable {
var eventData: Event
typealias UIViewControllerType = SFSafariViewController
func makeUIViewController(context: Context) -> SFSafariViewController {
let url = URL(string: eventData.eventUrl)
return SFSafariViewController(url: url!)
}
func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {
}
}
struct ConnpassEventDetailView_Previews: PreviewProvider {
static var eventData = ConnpassTopViewModel().eventData
static var previews: some View {
ConnpassEventDetailView(eventData: eventData?[0] ?? Event.init(id: 0, title: "hoge", eventUrl: "hoge"))
}
}
마지막으로
전체적으로 적은 코드 양으로 끝났습니다. SwiftUI는 UIKit에 비해 기술량이 줄어들기 쉽다고 생각했습니다. 아직 나는 UIKit 쪽이 구현에 걸리는 시간이 짧습니다만, SwiftUI에 익숙해지면 개발이 폭속으로 진행된다고 생각했습니다. Combine에 관해서는 아직 지식이 부족하기 때문에 정진합니다 ...
기존의 라이브러리도 SwiftUI에 대응한 것은 적고, 아직 잠시는 UIKit를 사용한 개발이 주류일까라고 생각했습니다.
Reference
이 문제에 관하여(SwiftUI+URLSession+Combine에서 API를 두드려 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/KaitoKudou/items/dc89a25bc2cd74449aa6
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(SwiftUI+URLSession+Combine에서 API를 두드려 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/KaitoKudou/items/dc89a25bc2cd74449aa6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)