2017-04-03 8 views
0

Ist es möglich, optionale Initialisierungsparameter in Swift zu erstellen, damit ich ein Objekt aus JSON mit den vom API-Aufruf zurückgegebenen Werten erstellen kann, aber wenn ich das Objekt später speichere, kann ich auch die heruntergeladenen speichern UIImage für eine der URLs, die ich vorher bekommen habe.Swift 3 optionale Parameter

Beispiel:

class Story: NSObject, NSCoding { 
     var id: Int? 
     var title, coverImageURL: String? 
     var coverImage: UIImage? 

    required init?(anId: Int?, aTitle: String?, aCoverImageURL: String?) { 
      self.id = anId 
      self.title = aTitle 
      self.coverImageURL = aCoverImageURL 
    } 
    convenience init?(json: [String: Any]) { 
      let id = json["id"] as? Int 
      let title = json["title"] as? String 
      let coverImageURL = json["cover_image"] as? String 

      self.init(
       anId: id, 
       aTitle: title, 
       aCoverImageURL: coverImageURL, 
      ) 
     } 

Dann Später möchte ich Objekte in den Speicher Sinn

//MARK: Types 
    struct PropertyKey { 
     static let id = "id" 
     static let title = "title" 
     static let coverImageURL = "coverImageURL" 
     static let coverImage = "coverImage" 
    } 

    //MARK: NSCoding 
    func encode(with aCoder: NSCoder) { 
     aCoder.encode(id, forKey: PropertyKey.id) 
     aCoder.encode(title, forKey: PropertyKey.title) 
     aCoder.encode(coverImageURL, forKey: PropertyKey.coverImageURL) 
     aCoder.encode(coverImage, forKey: PropertyKey.coverImage) 
    } 

    required convenience init?(coder aDecoder: NSCoder) { 
     guard let id = aDecoder.decodeObject(forKey: PropertyKey.id) as? Int else { 
      os_log("Unable to decode the id for a Story object.", log: OSLog.default, type: .debug) 
      return nil 
     } 
     guard let title = aDecoder.decodeObject(forKey: PropertyKey.title) as? String else { 
      os_log("Unable to decode the title for a Story object.", log: OSLog.default, type: .debug) 
      return nil 
     } 

     let coverImageURL = aDecoder.decodeObject(forKey: PropertyKey.coverImageURL) as? String 
     let coverImage = aDecoder.decodeObject(forKey: PropertyKey.coverImage) as? UIImage 

     self.init(
      anId: id, 
      aTitle: title, 
      aCoverImageURL: coverImageURL, 
      coverImage: coverImage, 
     ) 
    } 

Macht dies zu retten? Ich möchte in der Lage sein, ein Story-Objekt zu speichern, sobald ich die Antwort von der API erhalte, aber später, wenn ich die Geschichte in den Speicher speichere, möchte ich die abgerufene UIImage für das CoverImage speichern können.

Wie würde ich das tun?

+1

Also nur coverImage sollte optional sein –

+0

BTW müssen Sie Ihre UIImage in Daten konvertieren, um es auf der Festplatte speichern zu können (encode) –

+0

@LeoDabus richtig. – Arel

Antwort

0

Ich bin mir nicht sicher, warum niemand die einfachen Punkte auf diese Antwort genommen hat, aber die Antwort ist, einfach Ihre Eigenschaften Optionals zu machen, und dann können Sie sie mit einem Wert oder Null setzen. Sie können auch Convenience-Initialisierer erstellen, die bestimmte Werte automatisch auf Null setzen, wenn Sie möchten. Wenn ich meine App als Beispiel verwende, habe ich ein Modell, das aus einem API-Aufruf aufgebaut wird. Dieses Modell hat Werte wie id, created_at usw., die nicht existieren, bis ein Datensatz auf dem Server gespeichert wird, aber ich Objekte lokal erstellen, speichern und schließlich an den Server senden, also muss ich in der Lage sein, die nur über Werte, wenn ein Objekt aus JSON, also hier schaffen, ist, was ich tat:

class Story: NSObject, NSCoding { 
     var id: Int? 
     var title, coverImageURL: String? 
     var coverImage: UIImage? 

    required init?(anId: Int?, aTitle: String?, aCoverImageURL: String?) { 
      self.id = anId 
      self.title = aTitle 
      self.coverImageURL = aCoverImageURL 
    } 
    convenience init?(json: [String: Any]) { 
      let id = json["id"] as? Int 
      let title = json["title"] as? String 
      let coverImageURL = json["cover_image"] as? String 

      self.init(
       anId: id, 
       aTitle: title, 
       aCoverImageURL: coverImageURL, 
      ) 
     } 

     convenience init?(aTitle: String, aCoverImage: UIImage?) { 
      let title = aTitle 
      let subtitle = aSubtitle 
      let coverImage = aCoverImage 
      let isActive = activeStatus 

      self.init(
       anId: nil, 
       aTitle: title, 
       aCoverImageURL: nil, 
       aCoverImage: coverImage, 
      ) 
     } 

Wie Sie sehen können, habe ich nur zwei der Werte, wenn ich ein Objekt lokal bin zu schaffen, und die anderen Werte sind Setzen Sie einfach auf nil. Um einen Wert auf nil zu setzen, machen Sie es einfach zum Einstellen. Einfach!