Help us understand the problem. What is going on with this article?

Swift4のJSONDecorderは、Date等のパース方法をカスタマイズできるみたい

More than 1 year has passed since last update.

とりあえずサンプルコード

import Foundation

struct S1: Codable {
    let dateFromTimeInterval: Date
}

struct S2: Codable {
    let dateFromISO8601: Date
}

struct S3: Codable {
    let dateFromCustomFormat: Date
}

let data = """
{
    "dateFromTimeInterval": 540000000,
    "dateFromISO8601": "2017-01-01T12:34:56Z",
    "dateFromCustomFormat": "2034ねん03がつ04にち05じ06ふん07びょう",
}
""".data(using: .utf8)!

do {
    do {
        let decoder = JSONDecoder()
        let t = try decoder.decode(S1.self, from: data)
        print(t)
    }
    do {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601
        let t = try decoder.decode(S2.self, from: data)
        print(t)
    }
    do {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .formatted({
            let f = DateFormatter()
            f.calendar = Calendar(identifier: .gregorian)
            f.locale = .current
            f.dateFormat = "yyyyねんMMがつddにちHHじmmふんssびょう"
            return f
        }())

        let t = try decoder.decode(S3.self, from: data)
        print(t)
    }
    do {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .custom {
            let container = try $0.singleValueContainer()
            let str = try container.decode(String.self)
            let f = DateFormatter()
            f.calendar = Calendar(identifier: .gregorian)
            f.locale = .current
            f.dateFormat = "yyyyねんMMがつddにちHHじmmふんssびょう"
            return f.date(from: str)!
        }
        let t = try decoder.decode(S3.self, from: data)
        print(t)
    }
} catch {
    print(error)
}

/* 結果
S1(dateFromTimeInterval: 2018-02-11 00:00:00 +0000)
S2(dateFromISO8601: 2017-01-01 12:34:56 +0000)
S3(dateFromCustomFormat: 2034-03-04 13:06:07 +0000)
S3(dateFromCustomFormat: 2034-03-04 13:06:07 +0000)
*/

Date以外も、Strategyとして設定できるものはいくつかあるみたい

    /// The strategy to use for decoding `Date` values.
    public enum DateDecodingStrategy {

        /// Defer to `Date` for decoding. This is the default strategy.
        case deferredToDate

        /// Decode the `Date` as a UNIX timestamp from a JSON number.
        case secondsSince1970

        /// Decode the `Date` as UNIX millisecond timestamp from a JSON number.
        case millisecondsSince1970

        /// Decode the `Date` as an ISO-8601-formatted string (in RFC 3339 format).
        case iso8601

        /// Decode the `Date` as a string parsed by the given formatter.
        case formatted(DateFormatter)

        /// Decode the `Date` as a custom value decoded by the given closure.
        case custom((Decoder) throws -> Date)
    }

    /// The strategy to use for decoding `Data` values.
    public enum DataDecodingStrategy {

        /// Decode the `Data` from a Base64-encoded string. This is the default strategy.
        case base64Decode

        /// Decode the `Data` as a custom value decoded by the given closure.
        case custom((Decoder) throws -> Data)
    }

    /// The strategy to use for non-JSON-conforming floating-point values (IEEE 754 infinity and NaN).
    public enum NonConformingFloatDecodingStrategy {

        /// Throw upon encountering non-conforming values. This is the default strategy.
        case `throw`

        /// Decode the values from the given representation strings.
        case convertFromString(positiveInfinity: String, negativeInfinity: String, nan: String)
    }

    /// The strategy to use in decoding dates. Defaults to `.deferredToDate`.
    open var dateDecodingStrategy: JSONDecoder.DateDecodingStrategy

    /// The strategy to use in decoding binary data. Defaults to `.base64Decode`.
    open var dataDecodingStrategy: JSONDecoder.DataDecodingStrategy

    /// The strategy to use in decoding non-conforming numbers. Defaults to `.throw`.
    open var nonConformingFloatDecodingStrategy: JSONDecoder.NonConformingFloatDecodingStrategy

ちなみに、JSONDecoder だけでなく JSONEncoder 側にもカスタマイズ可能なプロパティがいくつかあるので覚えておくとよさそう

参考リンク

JSONDecoder - Foundation | Apple Developer Documentation
JSONEncoder - Foundation | Apple Developer Documentation

takasek
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした