সুইফট ডিকোডেবল প্রোটোকলের সাহায্যে নেস্টেড জেএসএন কাঠামো কীভাবে ডিকোড করবেন?


90

এখানে আমার JSON

{
    "id": 1,
    "user": {
        "user_name": "Tester",
        "real_info": {
            "full_name":"Jon Doe"
        }
    },
    "reviews_count": [
        {
            "count": 4
        }
    ]
}

এখানে যে কাঠামোটি এটি সংরক্ষণ করতে চাই তা এখানে (অসম্পূর্ণ)

struct ServerResponse: Decodable {
    var id: String
    var username: String
    var fullName: String
    var reviewCount: Int

    enum CodingKeys: String, CodingKey {
       case id, 
       // How do i get nested values?
    }
}

নেস্টেড স্ট্রাক্টগুলি ডিকোডিংয়ের বিষয়ে আমি অ্যাপলের ডকুমেন্টেশনের দিকে নজর রেখেছি , তবে জেএসএনের বিভিন্ন স্তরের কীভাবে সঠিকভাবে করা যায় তা আমি এখনও বুঝতে পারি না। যে কোন সাহায্যের জন্য অনেক প্রশংসা করা হবে।

উত্তর:


109

আর একটি পদ্ধতি হল একটি মধ্যবর্তী মডেল তৈরি করা যা জেএসওনের সাথে ঘনিষ্ঠভাবে মিলিত হয় ( কুইকটাইপ.আইওর মতো সরঞ্জামের সাহায্যে ), সুইফটটি এটিকে ডিকোড করার পদ্ধতিগুলি তৈরি করতে দিন এবং তারপরে আপনার চূড়ান্ত ডেটা মডেলটিতে আপনি যে টুকরো চান তা বেছে নিন:

// snake_case to match the JSON and hence no need to write CodingKey enums / struct
fileprivate struct RawServerResponse: Decodable {
    struct User: Decodable {
        var user_name: String
        var real_info: UserRealInfo
    }

    struct UserRealInfo: Decodable {
        var full_name: String
    }

    struct Review: Decodable {
        var count: Int
    }

    var id: Int
    var user: User
    var reviews_count: [Review]
}

struct ServerResponse: Decodable {
    var id: String
    var username: String
    var fullName: String
    var reviewCount: Int

    init(from decoder: Decoder) throws {
        let rawResponse = try RawServerResponse(from: decoder)

        // Now you can pick items that are important to your data model,
        // conveniently decoded into a Swift structure
        id = String(rawResponse.id)
        username = rawResponse.user.user_name
        fullName = rawResponse.user.real_info.full_name
        reviewCount = rawResponse.reviews_count.first!.count
    }
}

এটি আপনাকে সহজেই পুনরাবৃত্তি করতে দেয় reviews_count, ভবিষ্যতে এটিতে 1 টিরও বেশি মান থাকা উচিত।


ঠিক আছে. এই পদ্ধতির খুব পরিষ্কার দেখাচ্ছে। আমার ক্ষেত্রে, আমি মনে করি আমি এটি ব্যবহার করব
ফ্লো ইউআই। সিম্পলআইটিস্টিং.কম

হ্যাঁ আমি অবশ্যই এটিকে উচ্ছেদ করেছি - @ জেটি অ্যাপ্লিক্যালক্যালেন্ডারফায়োসস সুইফ্ট আপনার এটি গ্রহণ করা উচিত, কারণ এটি আরও ভাল সমাধান।
হামিশ

@ হামিশ ঠিক আছে আমি এটি পরিবর্তন করেছি, তবে আপনার উত্তরটি অত্যন্ত বিশদ ছিল। আমি এটি থেকে অনেক কিছু শিখেছি।
ফ্লোইউআই সিম্পলইউটিস্টিং ডটকম

আমি জানতে আগ্রহী যে একই পদ্ধতির অনুসরণ করে কেউ কীভাবে কাঠামোর Encodableজন্য বাস্তবায়ন করতে পারে ServerResponse। এটা কি সম্ভব?
নায়েম 25'18

4
@ নায়েম সমস্যাটির ServerResponseতুলনায় ডেটা কম রয়েছে RawServerResponse। আপনি RawServerResponseউদাহরণটি ক্যাপচার করতে পারেন , এর থেকে বৈশিষ্ট্যগুলি সহ এটি আপডেট করতে পারেন ServerResponse, তারপরে সেখান থেকে জেএসএন তৈরি করতে পারেন । আপনি যে নির্দিষ্ট সমস্যার মুখোমুখি হচ্ছেন তার সাথে একটি নতুন প্রশ্ন পোস্ট করে আপনি আরও ভাল সহায়তা পেতে পারেন।
কোড ভিন্ন

95

আপনার সমস্যা সমাধানের জন্য, আপনি নিজের RawServerResponseপ্রয়োগটিকে কয়েকটি যুক্তিযুক্ত অংশে বিভক্ত করতে পারেন (সুইফট 5 ব্যবহার করে)।


# 1 বৈশিষ্ট্য এবং প্রয়োজনীয় কোডিং কীগুলি বাস্তবায়ন করুন

import Foundation

struct RawServerResponse {

    enum RootKeys: String, CodingKey {
        case id, user, reviewCount = "reviews_count"
    }

    enum UserKeys: String, CodingKey {
        case userName = "user_name", realInfo = "real_info"
    }

    enum RealInfoKeys: String, CodingKey {
        case fullName = "full_name"
    }

    enum ReviewCountKeys: String, CodingKey {
        case count
    }

    let id: Int
    let userName: String
    let fullName: String
    let reviewCount: Int

}

# 2 idসম্পত্তির জন্য ডিকোডিং কৌশল সেট করুন

extension RawServerResponse: Decodable {

    init(from decoder: Decoder) throws {
        // id
        let container = try decoder.container(keyedBy: RootKeys.self)
        id = try container.decode(Int.self, forKey: .id)

        /* ... */                 
    }

}

# 3। userNameসম্পত্তির জন্য ডিকোডিং কৌশল সেট করুন

extension RawServerResponse: Decodable {

    init(from decoder: Decoder) throws {
        /* ... */

        // userName
        let userContainer = try container.nestedContainer(keyedBy: UserKeys.self, forKey: .user)
        userName = try userContainer.decode(String.self, forKey: .userName)

        /* ... */
    }

}

# 4 fullNameসম্পত্তির জন্য ডিকোডিং কৌশল সেট করুন

extension RawServerResponse: Decodable {

    init(from decoder: Decoder) throws {
        /* ... */

        // fullName
        let realInfoKeysContainer = try userContainer.nestedContainer(keyedBy: RealInfoKeys.self, forKey: .realInfo)
        fullName = try realInfoKeysContainer.decode(String.self, forKey: .fullName)

        /* ... */
    }

}

# 5 reviewCountসম্পত্তির জন্য ডিকোডিং কৌশল সেট করুন

extension RawServerResponse: Decodable {

    init(from decoder: Decoder) throws {
        /* ...*/        

        // reviewCount
        var reviewUnkeyedContainer = try container.nestedUnkeyedContainer(forKey: .reviewCount)
        var reviewCountArray = [Int]()
        while !reviewUnkeyedContainer.isAtEnd {
            let reviewCountContainer = try reviewUnkeyedContainer.nestedContainer(keyedBy: ReviewCountKeys.self)
            reviewCountArray.append(try reviewCountContainer.decode(Int.self, forKey: .count))
        }
        guard let reviewCount = reviewCountArray.first else {
            throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: container.codingPath + [RootKeys.reviewCount], debugDescription: "reviews_count cannot be empty"))
        }
        self.reviewCount = reviewCount
    }

}

সম্পূর্ণ বাস্তবায়ন

import Foundation

struct RawServerResponse {

    enum RootKeys: String, CodingKey {
        case id, user, reviewCount = "reviews_count"
    }

    enum UserKeys: String, CodingKey {
        case userName = "user_name", realInfo = "real_info"
    }

    enum RealInfoKeys: String, CodingKey {
        case fullName = "full_name"
    }

    enum ReviewCountKeys: String, CodingKey {
        case count
    }

    let id: Int
    let userName: String
    let fullName: String
    let reviewCount: Int

}
extension RawServerResponse: Decodable {

    init(from decoder: Decoder) throws {
        // id
        let container = try decoder.container(keyedBy: RootKeys.self)
        id = try container.decode(Int.self, forKey: .id)

        // userName
        let userContainer = try container.nestedContainer(keyedBy: UserKeys.self, forKey: .user)
        userName = try userContainer.decode(String.self, forKey: .userName)

        // fullName
        let realInfoKeysContainer = try userContainer.nestedContainer(keyedBy: RealInfoKeys.self, forKey: .realInfo)
        fullName = try realInfoKeysContainer.decode(String.self, forKey: .fullName)

        // reviewCount
        var reviewUnkeyedContainer = try container.nestedUnkeyedContainer(forKey: .reviewCount)
        var reviewCountArray = [Int]()
        while !reviewUnkeyedContainer.isAtEnd {
            let reviewCountContainer = try reviewUnkeyedContainer.nestedContainer(keyedBy: ReviewCountKeys.self)
            reviewCountArray.append(try reviewCountContainer.decode(Int.self, forKey: .count))
        }
        guard let reviewCount = reviewCountArray.first else {
            throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: container.codingPath + [RootKeys.reviewCount], debugDescription: "reviews_count cannot be empty"))
        }
        self.reviewCount = reviewCount
    }

}

ব্যবহার

let jsonString = """
{
    "id": 1,
    "user": {
        "user_name": "Tester",
        "real_info": {
            "full_name":"Jon Doe"
        }
    },
    "reviews_count": [
    {
    "count": 4
    }
    ]
}
"""

let jsonData = jsonString.data(using: .utf8)!
let decoder = JSONDecoder()
let serverResponse = try! decoder.decode(RawServerResponse.self, from: jsonData)
dump(serverResponse)

/*
prints:
▿ RawServerResponse #1 in __lldb_expr_389
  - id: 1
  - user: "Tester"
  - fullName: "Jon Doe"
  - reviewCount: 4
*/

13
খুব নিবেদিত উত্তর।
Hexfire

4
পরিবর্তে structআপনি enumচাবি দিয়ে ব্যবহৃত । যা অনেক বেশি মার্জিত 👍
জ্যাক

4
এটিকে এত ভালভাবে ডকুমেন্ট করার জন্য সময় দেওয়ার জন্য একটি বিশাল ধন্যবাদ। ডিকোডেবল এবং জেএসওনকে বিশ্লেষণের বিষয়ে এতগুলি ডকুমেন্টেশনগুলি ছড়িয়ে দেওয়ার পরে, আপনার উত্তর সত্যিই আমার অনেক প্রশ্ন সাফ করেছে।
মারসি

30

আপনার জেএসএনকে ডিকোড করার জন্য প্রয়োজনীয় সমস্ত কীগুলির CodingKeysসাথে একটি বড় অঙ্কের পরিবর্তে , স্তরক্রমটি সংরক্ষণের জন্য নেস্টেড গণনাগুলি ব্যবহার করে আপনার প্রতিটি নেস্টেড জেএসওএন অবজেক্টের জন্য কীগুলি বিভক্ত করার পরামর্শ দেব :

// top-level JSON object keys
private enum CodingKeys : String, CodingKey {

    // using camelCase case names, with snake_case raw values where necessary.
    // the raw values are what's used as the actual keys for the JSON object,
    // and default to the case name unless otherwise specified.
    case id, user, reviewsCount = "reviews_count"

    // "user" JSON object keys
    enum User : String, CodingKey {
        case username = "user_name", realInfo = "real_info"

        // "real_info" JSON object keys
        enum RealInfo : String, CodingKey {
            case fullName = "full_name"
        }
    }

    // nested JSON objects in "reviews" keys
    enum ReviewsCount : String, CodingKey {
        case count
    }
}

এটি আপনার জেএসএন-এর প্রতিটি স্তরে কীগুলি ট্র্যাক করা সহজ করবে।

এখন, মনে রাখবেন যে:

  • একটি কীড কনটেইনারটি জেএসওএন অবজেক্টটি ডিকোড করার জন্য ব্যবহৃত হয় এবং একটি CodingKeyকনফার্মিং টাইপ (যেমন আমরা উপরে সংজ্ঞায়িত করেছি) দিয়ে ডিকোড করা হয় ।

  • একটি unkeyed ধারক একটি JSON- অ্যারের ডিকোড করতে ব্যবহৃত হয়, এবং সঙ্কেতমুক্ত হয় ক্রমানুসারে (অর্থাত প্রতিটি সময় আপনি এটি একটি ডিকোড বা নেস্টেড ধারক পদ্ধতি কল, এটা অ্যারের মধ্যে পরবর্তী উপাদানে এগিয়ে)। আপনি কীভাবে একটির মাধ্যমে পুনরাবৃত্তি করতে পারেন তার উত্তরের দ্বিতীয় অংশটি দেখুন।

ডিকোডার থেকে আপনার শীর্ষ-স্তরের কীড পাত্রে পাওয়ার পরে container(keyedBy:)(যেমন আপনার শীর্ষ স্তরের একটি জেএসওএন অবজেক্ট রয়েছে), আপনি বারবার পদ্ধতিগুলি ব্যবহার করতে পারেন:

  • nestedContainer(keyedBy:forKey:) প্রদত্ত কীটির জন্য কোনও অবজেক্ট থেকে নেস্টেড অবজেক্ট পেতে
  • nestedUnkeyedContainer(forKey:) প্রদত্ত কীটির জন্য কোনও অবজেক্ট থেকে নেস্টেড অ্যারে পেতে
  • nestedContainer(keyedBy:) একটি অ্যারের থেকে পরবর্তী নেস্টেড অবজেক্টটি পেতে
  • nestedUnkeyedContainer() একটি অ্যারে থেকে পরবর্তী নেস্টেড অ্যারে পেতে

উদাহরণ স্বরূপ:

struct ServerResponse : Decodable {

    var id: Int, username: String, fullName: String, reviewCount: Int

    private enum CodingKeys : String, CodingKey { /* see above definition in answer */ }

    init(from decoder: Decoder) throws {

        // top-level container
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(Int.self, forKey: .id)

        // container for { "user_name": "Tester", "real_info": { "full_name": "Jon Doe" } }
        let userContainer =
            try container.nestedContainer(keyedBy: CodingKeys.User.self, forKey: .user)

        self.username = try userContainer.decode(String.self, forKey: .username)

        // container for { "full_name": "Jon Doe" }
        let realInfoContainer =
            try userContainer.nestedContainer(keyedBy: CodingKeys.User.RealInfo.self,
                                              forKey: .realInfo)

        self.fullName = try realInfoContainer.decode(String.self, forKey: .fullName)

        // container for [{ "count": 4 }] – must be a var, as calling a nested container
        // method on it advances it to the next element.
        var reviewCountContainer =
            try container.nestedUnkeyedContainer(forKey: .reviewsCount)

        // container for { "count" : 4 }
        // (note that we're only considering the first element of the array)
        let firstReviewCountContainer =
            try reviewCountContainer.nestedContainer(keyedBy: CodingKeys.ReviewsCount.self)

        self.reviewCount = try firstReviewCountContainer.decode(Int.self, forKey: .count)
    }
}

ডিকোডিংয়ের উদাহরণ:

let jsonData = """
{
  "id": 1,
  "user": {
    "user_name": "Tester",
    "real_info": {
    "full_name":"Jon Doe"
  }
  },
  "reviews_count": [
    {
      "count": 4
    }
  ]
}
""".data(using: .utf8)!

do {
    let response = try JSONDecoder().decode(ServerResponse.self, from: jsonData)
    print(response)
} catch {
    print(error)
}

// ServerResponse(id: 1, username: "Tester", fullName: "Jon Doe", reviewCount: 4)

একটি অপরিশোধিত পাত্রে মাধ্যমে আইট্রেট করা

আপনি যেখানে reviewCountহতে চান সেই ক্ষেত্রে বিবেচনা করে [Int], যেখানে প্রতিটি উপাদান "count"নেস্টেড জেএসওএন-তে কীটির মান উপস্থাপন করে :

  "reviews_count": [
    {
      "count": 4
    },
    {
      "count": 5
    }
  ]

নেস্টেড আনকাইড কনটেইনারের মাধ্যমে আপনাকে পুনরাবৃত্তি করতে হবে, প্রতিটি পুনরাবৃত্তিতে নেস্টেড কীড পাত্রে পেয়ে এবং "count"কীটির জন্য মানটি ডিকোডিং করতে হবে । countফলস্বর অ্যারের প্রাক-বরাদ্দ করতে আপনি অপ্রয়োজনীয় ধারকটির সম্পত্তিটি ব্যবহার করতে পারেন এবং তারপরে isAtEndসম্পত্তিটি পুনরাবৃত্তি করতে পারেন।

উদাহরণ স্বরূপ:

struct ServerResponse : Decodable {

    var id: Int
    var username: String
    var fullName: String
    var reviewCounts = [Int]()

    // ...

    init(from decoder: Decoder) throws {

        // ...

        // container for [{ "count": 4 }, { "count": 5 }]
        var reviewCountContainer =
            try container.nestedUnkeyedContainer(forKey: .reviewsCount)

        // pre-allocate the reviewCounts array if we can
        if let count = reviewCountContainer.count {
            self.reviewCounts.reserveCapacity(count)
        }

        // iterate through each of the nested keyed containers, getting the
        // value for the "count" key, and appending to the array.
        while !reviewCountContainer.isAtEnd {

            // container for a single nested object in the array, e.g { "count": 4 }
            let nestedReviewCountContainer = try reviewCountContainer.nestedContainer(
                                                 keyedBy: CodingKeys.ReviewsCount.self)

            self.reviewCounts.append(
                try nestedReviewCountContainer.decode(Int.self, forKey: .count)
            )
        }
    }
}

একটি বিষয় পরিষ্কার করতে হবে: আপনি কী বোঝাতে চেয়েছেন I would advise splitting the keys for each of your nested JSON objects up into multiple nested enumerations, thereby making it easier to keep track of the keys at each level in your JSON?
ফ্লোইউআই সিম্পলআইটিস্টিং.কম

@ জেটিএপ্লেক্যালেন্ডারফোরিওস সুইফট বলতে আমি বোঝাতে চাইছি যে আপনি আপনার জেএসওএন অবজেক্টটি ডিকোড করতে হবে এমন সমস্ত কীগুলির CodingKeysসাথে একটি বড় এনাম থাকার পরিবর্তে আপনার সেগুলি প্রতিটি জেএসএন অবজেক্টের জন্য একাধিক এনামে বিভক্ত করা উচিত - উদাহরণস্বরূপ, উপরের কোডটিতে কীগুলির সাথে আমাদের রয়েছে ব্যবহারকারীর JSON অবজেক্ট ( ) ডিকোড করতে , সুতরাং & এর জন্য কেবল কীগুলি । CodingKeys.User{ "user_name": "Tester", "real_info": { "full_name": "Jon Doe" } }"user_name""real_info"
হামিশ

ধন্যবাদ খুব পরিষ্কার সাড়া। আমি এটি এখনও পুরোপুরি বুঝতে এটি দেখতে চাই। কিন্তু এটি কাজ করে.
ফ্লোইউআই সিম্পলআইটিস্টিং ডটকম

reviews_countঅভিধানের একটি অ্যারে যা সম্পর্কে আমার একটি প্রশ্ন ছিল । বর্তমানে, কোডটি প্রত্যাশার মতো কাজ করে। আমার পর্যালোচনাগণনাটিতে অ্যারেতে কেবলমাত্র একটি মান রয়েছে। তবে আমি যদি আসলে রিভিউ_কাউন্টের একটি অ্যারে চাইতাম, তবে আমাকে কেবল var reviewCount: Intএকটি অ্যারের অধিকার হিসাবে ডিক্লেয়ার করতে হবে ? -> var reviewCount: [Int]। এবং তারপরে ReviewsCountআমারও সঠিকভাবে এনাম সম্পাদনা করা দরকার ?
ফ্লোইউআই সিম্পলআইটিস্টিং ডটকম

4
@ জেটিএপলক্যালেন্ডারফোরিওস সুইফটটি আসলে কিছুটা জটিল হবে কারণ আপনি যা বর্ণনা করছেন তা কেবল একটি অ্যারে নয় Int, জেএসওএন অবজেক্টের একটি অ্যারে যা প্রত্যেকের Intএকটি প্রদত্ত কীটির জন্য মূল্য রয়েছে - তাই আপনাকে যা করতে হবে তার মাধ্যমে পুনরাবৃত্তি হবে অপরিশোধিত ধারক এবং সমস্ত নেস্টেড কীড কনটেইনারগুলি পান, Intপ্রত্যেকটির জন্য একটি ডিকোডিং করুন (এবং তারপরে সেগুলি আপনার অ্যারে সংযোজন করুন), যেমন gist.github.com/hamishknight/9b5c202fe6d8289ee2cb9403876a1b41
হামিশ

4

অনেক ভাল উত্তর ইতিমধ্যে পোস্ট করা হয়েছে, কিন্তু একটি সহজ পদ্ধতি এখনও বর্ণিত নয় IMO।

যখন JSON ফিল্ডের নামগুলি ব্যবহার করে লেখা হয় snake_case_notationআপনি এখনও camelCaseNotationআপনার সুইফ্ট ফাইলটিতে এটি ব্যবহার করতে পারেন ।

আপনার শুধু সেট করা দরকার

decoder.keyDecodingStrategy = .convertFromSnakeCase

এই লাইনের পরে সুইফ্টটি স্বয়ংক্রিয়ভাবে জেএসএন থেকে শুরু করে সুইড্ট মডেলের snake_caseক্ষেত্রগুলিতে সমস্ত ক্ষেত্রের সাথে মিলবে camelCase

যেমন

user_name` -> userName
reviews_count -> `reviewsCount
...

এখানে সম্পূর্ণ কোড

1. মডেল রচনা

struct Response: Codable {

    let id: Int
    let user: User
    let reviewsCount: [ReviewCount]

    struct User: Codable {
        let userName: String

        struct RealInfo: Codable {
            let fullName: String
        }
    }

    struct ReviewCount: Codable {
        let count: Int
    }
}

2. ডিকোডার সেট করা হচ্ছে

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

3. ডিকোডিং

do {
    let response = try? decoder.decode(Response.self, from: data)
    print(response)
} catch {
    debugPrint(error)
}

4
বাসা বাঁধার বিভিন্ন স্তরের কীভাবে মোকাবেলা করা যায় তার মূল প্রশ্নটি এটি সমাধান করে না।
থিও

2
  1. জাসন ফাইলটি https://app.quicktype.io এ অনুলিপি করুন
  2. সুইফট নির্বাচন করুন (আপনি যদি সুইফট 5 ব্যবহার করেন তবে সুইফট 5 এর জন্য সামঞ্জস্যতা স্যুইচটি পরীক্ষা করুন)
  3. ফাইলটি ডিকোড করতে নিম্নলিখিত কোডটি ব্যবহার করুন
  4. ভয়েলা!
let file = "data.json"

guard let url = Bundle.main.url(forResource: "data", withExtension: "json") else{
    fatalError("Failed to locate \(file) in bundle.")
}

guard let data = try? Data(contentsOf: url) else{
    fatalError("Failed to locate \(file) in bundle.")
}

let yourObject = try? JSONDecoder().decode(YourModel.self, from: data)

4
আমার জন্য কাজ করেছেন, আপনাকে ধন্যবাদ। সেই সাইটটি সোনার। দর্শকদের জন্য, যদি জসন স্ট্রিং ভেরিয়েবলটি ডিকোড করে থাকেন তবে উপরের jsonStrদুটি guard letএর পরিবর্তে আপনি এটি ব্যবহার করতে পারেন : guard let jsonStrData: Data? = jsonStr.data(using: .utf8)! else { print("error") }তারপরে লাইনে jsonStrDataউপরে বর্ণিত হিসাবে আপনার কাঠামোতে রূপান্তর করুনlet yourObject
পি

এটি একটি আশ্চর্যজনক সরঞ্জাম!
পোস্টকোডিজম

0

এছাড়াও আপনি প্রস্তুত কৃত্রিম কোডেবল লাইব্রেরি ব্যবহার করতে পারেন । এটির জন্য কোড কম লাগবে। আমাকে যদি আপনি এটি সম্পর্কে কি জানি।

struct ServerResponse: Decodable, Keyedable {
  var id: String!
  var username: String!
  var fullName: String!
  var reviewCount: Int!

  private struct ReviewsCount: Codable {
    var count: Int
  }

  mutating func map(map: KeyMap) throws {
    var id: Int!
    try id <<- map["id"]
    self.id = String(id)

    try username <<- map["user.user_name"]
    try fullName <<- map["user.real_info.full_name"]

    var reviewCount: [ReviewsCount]!
    try reviewCount <<- map["reviews_count"]
    self.reviewCount = reviewCount[0].count
  }

  init(from decoder: Decoder) throws {
    try KeyedDecoder(with: decoder).decode(to: &self)
  }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.