JSONDecoder ayrıştırma zamanının DateDecodingStratejisi

JSON verilerini döndürmek için JSON Kod Çözücü seri API'sini kullandığımızda, genellikle saat alanındaki verileri Tarih türüne eşleriz, böylece Uygulama daha sonra bazı zaman hesaplama işlevlerini kullanabilir. Bununla birlikte, API tarafından döndürülen zamanın birçok biçimi vardır, bu nedenle JSONDecoder'a zamanın biçimini söylemeliyiz, böylece saati ayrıştırıp bir Tarih türü olarak saklayabilir.

Yukarıdaki üç API, sırasıyla farklı zaman biçimlerini döndürür

JSONDecoder ayrıştırma zamanının DateDecodingStratejisi

JSON'un saat biçimini JSONDecoder'ın dateDecodingStrategy'si aracılığıyla ayarlayabiliriz.

DateDecodingStrategy türü DateDecodingStrategy'dir.Aşağıdaki biçimler ayarlanabilir.Ardından, pratik örneklerle birkaç yaygın zaman biçimini tanıtalım.

enum DateDecodingStrategy {
case deferredToDate
case secondsSince1970
case millisecondsSince1970
case iso8601
case formatted(DateFormatter)
case custom((Decoder) throws -> Date)
}

Örnek: 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()
}

Saniye1970

Örnek: IG API.

https://www.instagram.com/lepetitprinceofficiel/?__a=1

Arka planda döndürülen zaman bir sayı dizisi olduğunda, 1 Ocak 1970'ten sonraki saniye sayısı olma olasılığı yüksektir. Ayrıca önce Xcode oyun alanında Date'i oluşturabilir ve oluşturulan Date'in makul olup olmadığını test etmek için timeIntervalSince1970 parametresini arka uca geçirebiliriz.

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()
}

milisaniye

Örnek: covid19uk API.

https://api.covid19uk.live/historyfigures

Daha önce belirtildiği gibi, arka plan tarafından döndürülen zaman bir dizi sayı olduğunda, 1970.1.1'den itibaren saniye sayısı olma olasılığı yüksektir, ancak aynı zamanda 1970.1.1'den milisaniye sayısı da olabilir. Bu nedenle, çok fazla sayıda anormal zaman elde etmek için saniye1970'i kullanırsanız, 1970'den beri milisaniyeyi tekrar denemeyi unutmayın.

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()
}

biçimlendirilmiş

Örnek: Mask 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()
}

özel

Örnek: Dcard API.

https://dcard.tw/_api/posts?popular=true

Neyse ki iOS SDK, iso8601'i ondalık nokta ile ayrıştırmaya yardımcı olmak için ISO8601DateFormatter'ı sağlar. Ancak, ISO8601DateFormatter bir DateFormatter değildir, ISO8601DateFormatter nesnesini .formatted () biçiminde geçiremeyiz.

Bu nedenle, yalnızca öldürücü numarayı kullanabiliriz, son yönteme güvenebiliriz, DateDecodingStrategy'nin özel durumu aracılığıyla zaman ayrıştırma programını kapatarak yazabiliriz.

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: "")
   }
})

ISO 8601 saniyeyi ondalık sayılarla ayrıştırmak için FractionalSeconds ile kullanın

Suggested posts

“O küçük ada her şeyi değiştirir”

Sürücü deneyimini yükseltmek için Lyft Canlı Etkinlikleri nasıl tasarladık?

“O küçük ada her şeyi değiştirir”

Yolculuk paylaşımı için ezber bozan bir şey Lyft'te yaptığımız her şey arasında, sürücüler ve sürücüler arasındaki alışmaların koreografisini yapmak en karmaşık ve önemli olanlardan biridir. Bu koreografiyi başarmak, Lyft'in pek çok şeyi iyi yapmasına bağlıdır, ancak yalnızca binicileri hıza uydurmak çok önemlidir.

Uygulama Yaşam Döngüsü

Uygulama Yaşam Döngüsü

: Uygulama başlatmadan kapatmaya döngü: Bellek veya verileri yöneterek kullanılabilirlik ⬆️ Güvenlik işlenebilir UIApplication, AppDelegate durumu: AppDelegate nesnesinin UIApplication nesnesinden gönderilen mesajı aldığı ve her birini yürüttüğü işlevleri tanımlar Çalışmıyor: Uygulamanın çalışmadığı durum Etkin değil: Uygulamanın çalıştığı ancak hiçbir etkinliğin alınmadığı durum Etkin: Uygulamanın çalıştığı ve bir olayın meydana geldiği durum Arka Plan: Uygulamanın arka planda olduğu ancak yürütülmekte olan kodun bulunduğu durum Askıya Alındı: Uygulamanın bulunduğu durum arka plan ve kod çalıştırma, AppDelegate.swift dosyasında delege işlevleri olacak SceneDelegate iOS 13'ten itibaren desteklenen çoklu sahne işlevine iyi yanıt vermek için AppDelegate / SceneDelegate AppDelegate 1.

Related posts

"Mariana Çukuru Ortaya Çıktı: Uçurumun Korkunç Gizli Gerçeklerini Ortaya Çıkarmak"

"Mariana Çukuru Ortaya Çıktı: Uçurumun Korkunç Gizli Gerçeklerini Ortaya Çıkarmak"

Giriş: Cesur okuyucular, bizi gezegenimizin en karanlık derinliklerine götürecek bir yolculuğa hoş geldiniz. Bu blogda, Mariana Çukuru'nun esrarengiz dünyasına dalıyor, onun gizli sırlarını açığa çıkarıyor ve yüzeyinin altında yatan tüyler ürpertici gerçekleri ortaya çıkarıyoruz.

Güvenli Bir Çalışma Ortamı Oluşturma

Güvenli Bir Çalışma Ortamı Oluşturma

"Ben tehlikedeyken beni koruyacak. Beni çadırına saklayacak.

Sadece Bir Telefon Numarasıyla Herkesi Takip Edin | OSINT Soruşturması

Sadece Bir Telefon Numarasıyla Herkesi Takip Edin | OSINT Soruşturması

Bir OSINT Araştırmacısı, CTF Oyuncusu veya yalnızca istenmeyen aramalar alan biri olabilirsiniz. Bir reklamda gördüğünüz numarayı doğrulamaya çalışan biri.

Bir podcast'i etkili kılan nedir?

Bir podcast'i etkili kılan nedir?

Geçen hafta PressGazette (İngiliz medya haber sitesi) aracılığıyla gönderilen bir basın bildirisi fark ettim. Makale, Scandi podcast barındırma ve reklamcılık şirketi Acast'ın podcasting alanında "muhtemelen en etkili" yayıncılardan oluşan bir konsorsiyuma liderlik edeceğini duyurdu.