JSONDecoder 직렬 API에서 반환 된 JSON 데이터를 사용할 때 일반적으로 앱에서 시간 계산 함수를 사용할 수 있도록 시간 필드의 데이터를 날짜 유형에 매핑합니다. 그러나 API가 반환하는 시간에는 많은 형식이 있으므로 JSONDecoder에 시간 형식을 알려야 시간을 구문 분석하고 날짜 형식으로 저장할 수 있습니다.
JSONDecoder의 dateDecodingStrategy를 통해 JSON의 시간 형식을 설정할 수 있습니다.
dateDecodingStrategy의 유형은 DateDecodingStrategy이며 다음과 같은 형식을 설정할 수 있습니다. 다음으로 몇 가지 일반적인 시간 형식을 실제 예제와 함께 소개하겠습니다.
enum DateDecodingStrategy {
case deferredToDate
case secondsSince1970
case millisecondsSince1970
case iso8601
case formatted(DateFormatter)
case custom((Decoder) throws -> Date)
}
예 : iTunes API.
https://itunes.apple.com/search?term=beatles&media=music
struct ItunesResult: Decodable {
let results: [Song]
}
struct Song: Decodable {
let trackName: String
let releaseDate: Date
}
if let url = URL(string: "https://itunes.apple.com/search?term=beatles&media=music") {
URLSession.shared.dataTask(with: url) { (data, response, error) in
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
if let data = data, let itunesResult = try? decoder.decode(ItunesResult.self, from: data) {
print(itunesResult.results.first)
}
}.resume()
}
예 : IG API.
https://www.instagram.com/lepetitprinceofficiel/?__a=1
백그라운드에서 반환 된 시간이 숫자 문자열 인 경우 1970.1.1에서 초 수일 가능성이 높습니다. 먼저 Xcode 플레이 그라운드에서 Date를 생성하고 timeIntervalSince1970 매개 변수를 백엔드에 전달하여 생성 된 Date가 합리적인지 테스트 할 수 있습니다.
struct IGResult: Decodable {
let graphql: Graphql
}
struct Graphql: Decodable {
let user: User
}
struct User: Decodable {
let edgeOwnerToTimelineMedia: TimelineMedia
}
struct TimelineMedia: Decodable {
let edges: [Edge]
}
struct Edge: Decodable {
let node: Node
}
struct Node: Decodable {
let takenAtTimestamp: Date
}
if let url = URL(string: "https://www.instagram.com/lepetitprinceofficiel/?__a=1") {
URLSession.shared.dataTask(with: url) { (data, response, error) in
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .secondsSince1970
if let data = data, let igResult = try? decoder.decode(IGResult.self, from: data) {
print(igResult.graphql.user.edgeOwnerToTimelineMedia.edges.first?.node.takenAtTimestamp)
}
}.resume()
}
예 : covid19uk API.
https://api.covid19uk.live/historyfigures
앞서 언급했듯이 백그라운드에서 반환 된 시간이 일련의 숫자 인 경우 1970.1.1의 초 수일 확률이 높지만 1970.1.1의 밀리 초 수도있을 수 있습니다. 따라서 secondsSince1970을 사용하여 매우 많은 수의 비정상적인 시간을 얻는 경우 millisecondsSince1970을 다시 시도하는 것을 잊지 마십시오.
struct CovidData: Decodable {
let data: [Record]
}
struct Record: Decodable {
let date: Date
}
if let url = URL(string: "https://api.covid19uk.live/historyfigures") {
URLSession.shared.dataTask(with: url) { (data, response, error) in
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .millisecondsSince1970
if let data = data, let covidData = try? decoder.decode(CovidData.self, from: data) {
print(covidData.data.first?.date)
}
}.resume()
}
예 : 마스크 API.
https://quality.data.gov.tw/dq_download_json.php?nid=116285&md5_url=2150b333756e64325bdbc4a5fd45fad1
struct Mask: Decodable {
let name: String
let time: Date
enum CodingKeys: String, CodingKey {
case name = "醫事機構名稱"
case time = "來源資料時間"
}
}
if let url = URL(string: "https://quality.data.gov.tw/dq_download_json.php?nid=116285&md5_url=2150b333756e64325bdbc4a5fd45fad1") {
URLSession.shared.dataTask(with: url) { (data, response, error) in
let decoder = JSONDecoder()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
decoder.dateDecodingStrategy = .formatted(dateFormatter)
if let data = data, let masks = try? decoder.decode([Mask].self, from: data) {
print(masks.first)
}
}.resume()
}
예 : Dcard API.
https://dcard.tw/_api/posts?popular=true
다행히 iOS SDK는 ISO8601DateFormatter를 제공하여 소수점으로 iso8601을 구문 분석 할 수 있습니다. 그러나 ISO8601DateFormatter는 DateFormatter가 아니므로 .formatted ()에서 ISO8601DateFormatter 개체를 전달할 수 없습니다.
따라서 우리는 마지막 방법에 의존하여 DateDecodingStrategy의 사용자 정의 사례를 통해 종료로 시간 구문 분석 프로그램을 작성하는 킬러 트릭 만 사용할 수 있습니다.
struct Dcard: Decodable {
let title: String
let createdAt: Date
}
if let url = URL(string: "https://dcard.tw/_api/posts?popular=true") {
URLSession.shared.dataTask(with: url) { (data, response, error) in
let decoder = JSONDecoder()
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
let container = try decoder.singleValueContainer()
let dateString = try container.decode(String.self)
if let date = dateFormatter.date(from: dateString) {
return date
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "")
}
})
if let data = data, let dcards = try? decoder.decode([Dcard].self, from: data) {
print(dcards.first)
}
}.resume()
}
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
let container = try decoder.singleValueContainer()
let dateString = try container.decode(String.self)
if let date = dateFormatter.date(from: dateString) {
return date
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "")
}
})
withFractionalSeconds를 사용하여 ISO 8601 초를 소수로 구문 분석합니다.
차량 공유를 위한 게임 체인저 Lyft에서 우리가 하는 모든 일 중에서 라이더와 운전자 간의 픽업 안무는 가장 복잡하고 결과적인 것 중 하나입니다. 이 안무를 잘하는 것은 Lyft가 많은 일을 잘하는 것에 달려 있지만 단순히 라이더가 속도를 유지하는 것이 필수적입니다.
: 앱 시작부터 종료까지 주기 : 메모리나 데이터 관리로 사용성 ⬆️ 보안 처리 가능 UIApplication, AppDelegate 상황 : AppDelegate 객체가 UIApplication 객체에서 보낸 메시지를 받아 각각 실행하는 기능 정의 Not Running : 앱이 실행되고 있지 않은 상태Inactive : 앱이 실행되고 있지만 이벤트가 수신되지 않은 상태활성: 앱이 실행 중이고 이벤트가 발생한 상태백그라운드: 앱이 백그라운드에 있지만 코드가 실행 중인 상태서스펜드: 앱이 실행 중인 상태 AppDelegate.swift 파일 SceneDelegate에서 델리게이트 기능이 될 코드를 백그라운드에서 실행하지 않고 실행 iOS 13 이상부터 지원하는 다중 씬 기능에 잘 대응하기 위해 AppDelegate / SceneDelegate AppDelegate 1.
소개:용감한 독자 여러분, 지구의 가장 어두운 곳으로 우리를 데려다 줄 여행에 오신 것을 환영합니다. 이 블로그에서 우리는 Mariana Trench의 수수께끼 같은 세계를 탐구하여 숨겨진 비밀을 밝히고 그 표면 아래에 있는 뼛속까지 오싹해지는 진실을 밝혀냅니다.
햇빛의 첫 번째 광선이 평원의 서리가 내린 풀을 비추는 서쪽 언덕의 눈부신 황금빛 아침입니다. 온화하고 거대한 새까만 앵거스 소 떼가 일출을 배경으로 윤곽을 그리며 다져진 길을 따라 모두가 잘 아는 지역으로 향합니다. 조식 바.
오늘날과 같이 급변하고 경쟁이 치열한 세상에서 경력은 개인의 성장, 재정적 안정 및 전반적인 삶의 만족도에 중요한 역할을 합니다. 그러나 많은 사람들은 침체와 불만족의 끊임없는 순환에 휩싸여 직업 생활에서 점차 쇠퇴하고 있습니다.