কীভাবে সুইফট 4 এর কোডেবল থেকে বৈশিষ্ট্যগুলি বাদ দেওয়া যায়


104

সুইফট 4 এর নতুন Encodable/ Decodableপ্রোটোকলগুলি JSON (ডি) সিরিয়ালিকেশনটিকে বেশ মনোরম করে। যাইহোক, কোন বৈশিষ্ট্য এনকোড করা উচিত এবং কোনটি ডিকোড করা উচিত তার উপর সূক্ষ্ম-দানাযুক্ত নিয়ন্ত্রণ পাওয়ার কোনও উপায় আমি এখনও পাইনি।

আমি লক্ষ্য করেছি যে অনুষঙ্গী CodingKeysএনাম থেকে সম্পত্তি বাদ দিয়ে সম্পত্তিটি পুরোপুরি প্রক্রিয়া থেকে বাদ দেওয়া হয়, তবে কী আরও সুক্ষ্ম নিয়ন্ত্রণের উপায় আছে?


আপনি কি বলছেন আপনার এমন একটি মামলা রয়েছে যেখানে আপনার কয়েকটি সম্পত্তি রয়েছে যা আপনি এনকোড করতে চান তবে বিভিন্ন বৈশিষ্ট্য যা আপনি ডিকোড করতে চান? (যেমন আপনি চান যে আপনার ধরণটি গোল-ট্রিপযোগ্য না হয়?) কারণ আপনি যদি সম্পত্তিটি বাদ দেওয়ার বিষয়ে চিন্তা করেন তবে এটিকে একটি ডিফল্ট মান দেওয়া এবং এটি CodingKeysএনামের বাইরে রেখে দেওয়া যথেষ্ট।
Itai Ferber

নির্বিশেষে, আপনি সর্বদা প্রক্রিয়াটির সম্পূর্ণ নিয়ন্ত্রণের জন্য ম্যানুয়ালি Codableপ্রোটোকলের প্রয়োজনীয়তা ( init(from:)এবং encode(to:)) প্রয়োগ করতে পারেন ।
Itai Ferber

আমার নির্দিষ্ট ব্যবহারের ক্ষেত্রে হ'ল একটি ডিকোডারকে অত্যধিক নিয়ন্ত্রণ দেওয়া এড়ানো, যা অভ্যন্তরীণ সম্পত্তি মানগুলি ওভাররাইট করা থেকে দূরবর্তীভাবে জেএসএন থেকে প্রাপ্ত হতে পারে। নীচের সমাধানগুলি পর্যাপ্ত!
রামওয়াইম্যাট

4
আমি একটি উত্তর / নতুন সুইফ্ট বৈশিষ্ট্যটি দেখতে চাই যাতে আপনার বিশেষত সমস্ত সম্পত্তি যেগুলি সাধারণত বিনামূল্যে পাওয়া উচিত সেগুলি পুনরায় বাস্তবায়ন না করে কেবল বিশেষ কেসগুলি এবং বর্জনিত কীগুলি পরিচালনা করা প্রয়োজন hand
পেকম্ব

উত্তর:


182

এনকোড / ডিকোড করার কীগুলির তালিকাটি টাইপ করে CodingKeys( sশেষের দিকে নোট করুন ) দ্বারা নিয়ন্ত্রণ করা হয় । সংকলকটি আপনার জন্য এটি সংশ্লেষিত করতে পারে তবে সর্বদা এটি ওভাররাইড করতে পারে।

ধরা যাক আপনি nicknameএনকোডিং এবং ডিকোডিং উভয় থেকে সম্পত্তি বাদ দিতে চান :

struct Person: Codable {
    var firstName: String
    var lastName: String
    var nickname: String?

    private enum CodingKeys: String, CodingKey {
        case firstName, lastName
    }
}

আপনি যদি এটি অসম্পূর্ণ হতে চান (যেমন এনকোড তবে ডিকোড বা তদ্বিপরীত নয়), আপনার নিজের প্রয়োগগুলি সরবরাহ করতে হবে encode(with encoder: )এবং init(from decoder: ):

struct Person: Codable {
    var firstName: String
    var lastName: String

    // Since fullName is a computed property, it's excluded by default
    var fullName: String {
        return firstName + " " + lastName
    }

    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName
        case fullName
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        firstName = try container.decode(String.self, forKey: .firstName)
        lastName = try container.decode(String.self, forKey: .lastName)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(firstName, forKey: .firstName)
        try container.encode(lastName, forKey: .lastName)
        try container.encode(fullName, forKey: .fullName)
    }
}

17
nicknameএটি কাজ করার জন্য আপনাকে একটি ডিফল্ট মান দিতে হবে । অন্যথায়, সম্পত্তিটির জন্য নির্ধারিত কোনও মূল্য নেই init(from:)
Itai Ferber

4
@ ইতাইফারবার আমি এটিকে একটি alচ্ছিকটিতে স্যুইচ করেছি, যা মূলত আমার এক্সকোডে ছিল
কোড ভিন্ন ভিন্ন

আপনি কি encodeঅসম্পূর্ণ উদাহরণ প্রদান নিশ্চিত ? যেহেতু এটি এখনও স্ট্যান্ডার্ড আচরণ, তাই আমি এটির প্রয়োজন বলে মনে করি না। শুধু decodeযে যেখানে অপ্রতিসাম্য থেকে আসছে যেহেতু।
মার্ক এ। ডোনোহো

4
@ মার্কিআইভ হ্যাঁ, আপনার দরকার আছে। যেহেতু fullNameকোনও সঞ্চিত বৈশিষ্ট্যে ম্যাপ করা যায় না, তাই আপনাকে অবশ্যই একটি কাস্টম এনকোডার এবং ডিকোডার সরবরাহ করতে হবে।
কোড আলাদা করুন

2

কাঠামোর বিশাল সংখ্যক বৈশিষ্ট্য থেকে যদি আমাদের কয়েকটি সংখ্যক বৈশিষ্ট্যের ডিকোডিং বাদ দিতে হয় তবে তাদের optionচ্ছিক বৈশিষ্ট্য হিসাবে ঘোষণা করুন। কোডিংকি এনামের অধীনে প্রচুর কী লিখার চেয়ে বিকল্পগুলি আন-র্যাপিং বিকল্পগুলি কম।

আমি গণিত উদাহরণ বৈশিষ্ট্য এবং গণনাযুক্ত ধরণের বৈশিষ্ট্য যুক্ত করতে এক্সটেনশনগুলি ব্যবহার করার পরামর্শ দেব। কোডেবল কমফর্মিং বৈশিষ্ট্যগুলি অন্যান্য যুক্তি থেকে পৃথক করে তাই আরও ভাল পঠনযোগ্যতা সরবরাহ করে।


2

এনকোডার থেকে কিছু সম্পত্তি বাদ দেওয়ার জন্য অন্য উপায়, পৃথক কোডিং ধারক ব্যবহার করা যেতে পারে

struct Person: Codable {
    let firstName: String
    let lastName: String
    let excludedFromEncoder: String

    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName
    }
    private enum AdditionalCodingKeys: String, CodingKey {
        case excludedFromEncoder
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let anotherContainer = try decoder.container(keyedBy: AdditionalCodingKeys.self)
        firstName = try container.decode(String.self, forKey: .firstName)
        lastName = try container.decode(String.self, forKey: .lastName)

        excludedFromEncoder = try anotherContainer(String.self, forKey: . excludedFromEncoder)
    }

    // it is not necessary to implement custom encoding
    // func encode(to encoder: Encoder) throws

    // let person = Person(firstName: "fname", lastName: "lname", excludedFromEncoder: "only for decoding")
    // let jsonData = try JSONEncoder().encode(person)
    // let jsonString = String(data: jsonData, encoding: .utf8)
    // jsonString --> {"firstName": "fname", "lastName": "lname"}

}

একই পদ্ধতির ডিকোডারের জন্য ব্যবহার করা যেতে পারে


1

আপনি গণিত বৈশিষ্ট্য ব্যবহার করতে পারেন:

struct Person: Codable {
  var firstName: String
  var lastName: String
  var nickname: String?

  var nick: String {
    get {
      nickname ?? ""
    }
  }

  private enum CodingKeys: String, CodingKey {
    case firstName, lastName
  }
}

এটি আমার জন্য একটি ক্লু ছিল - lazy varকার্যকরভাবে এটি রানটাইম সম্পত্তি হিসাবে কোডড থেকে বাদ দেওয়া হয়েছিল using
ক্রিসএইচ

0

এই যখন করতে কাজ করতে হবে এটা শেষ পর্যন্ত খুব হচ্ছে শেষ পর্যন্ত unSwifty এবং এমনকি unJSONy । আমি মনে করি আপনি দেখতে পাচ্ছেন যেখান থেকে, এস এর ধারণাটি #idএইচটিএমএলে প্রচলিত আছে, তবে এটি খুব কমই পৃথিবীতে স্থানান্তরিত হয় JSONযা আমি একটি ভাল জিনিস (টিএম) বিবেচনা করি ।

কিছু Codableস্ট্রাক্ট আপনার JSONফাইলটিকে পুনরাবৃত্ত হ্যাশগুলি ব্যবহার করে পুনর্গঠন করলে ঠিক আপনার ফাইলটি বিশ্লেষণ করতে সক্ষম হবে , অর্থাত আপনার যদি recipeঠিক এমন একটি অ্যারে থাকে ingredientsযা ঘুরে ফিরে (এক বা একাধিক) থাকে ingredient_info। এইভাবে পার্সারটি আপনাকে প্রথম স্থানে আপনার নেটওয়ার্ককে একত্রে সেলাই করতে সহায়তা করবে এবং আপনার যদি সত্যিই প্রয়োজন হয় তবে আপনাকে কেবল সাধারণ ট্র্যাভারসাল কাঠামোর মাধ্যমে কিছু ব্যাকলিঙ্ক সরবরাহ করতে হবে । যেহেতু এটির জন্য আপনার JSONএবং আপনার ডেটা কাঠামোর পুরোপুরি পুনর্নির্মাণের প্রয়োজন আমি আপনাকে কেবল এটি সম্পর্কে চিন্তাভাবনা করার জন্য স্কেচ করব। যদি আপনি এটি গ্রহণযোগ্য মনে করেন তবে দয়া করে আমাকে মন্তব্যগুলিতে বলুন তবে আমি এটি আরও বিশদভাবে জানাতে পারি, তবে পরিস্থিতিগুলির উপর নির্ভর করে আপনি তাদের কোনও একটি পরিবর্তন করার স্বাধীনতা থাকতে পারবেন না।


0

আমি ইমেজ (বা কোডড থেকে বাদ দেওয়া দরকার এমন কোনও সম্পত্তি) সেট করতে এবং পেতে অ্যাসোসিয়েটেডবজেক্টের সাথে প্রোটোকল এবং এর সম্প্রসারণ ব্যবহার করেছি।

এটির সাথে আমাদের নিজস্ব এনকোডার এবং ডিকোডার প্রয়োগ করতে হবে না

সরলতার জন্য প্রাসঙ্গিক কোড রেখে কোডটি এখানে:

protocol SCAttachmentModelProtocol{
    var image:UIImage? {get set}
    var anotherProperty:Int {get set}
}
extension SCAttachmentModelProtocol where Self: SCAttachmentUploadRequestModel{
    var image:UIImage? {
        set{
            //Use associated object property to set it
        }
        get{
            //Use associated object property to get it
        }
    }
}
class SCAttachmentUploadRequestModel : SCAttachmentModelProtocol, Codable{
    var anotherProperty:Int
}

এখন, যখনই আমরা চিত্রের বৈশিষ্ট্যটি অ্যাক্সেস করতে চাই আমরা প্রোটোকলের (এসসিএটিচচমেন্টমোডেলপ্রোটোকল) নিশ্চিতকরণকারী অবজেক্টটিতে ব্যবহার করতে পারি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.