Uploaded image for project: 'Swift'
  1. Swift
  2. SR-9300

Swift 4 Decodable does not suport Core Data update features

    XMLWordPrintable

    Details

      Description

      In Decodable protocol there is only one api 

      /// Creates a new instance by decoding from the given decoder.
      public init(from decoder: Decoder) throws

      Above method is already convenience init but still if we call 

      `self = existingUser` then it says. self is immutable.

      If we could have 

      onload

      or 

      oncomplete

       protocol methods also, then 

      we could fetch the existing managed object from core data and update with self.

       

      required convenience init(from decoder: Decoder) throws {
              // since we are decoding json to managedobject, so using background managedobject context
              guard let backgrounManagedObjectContext = CodingUserInfoKey.backgrounManagedObjectContext,
                  let parentLoginKey = CodingUserInfoKey.parentLogin,
                  let userTypeKey = CodingUserInfoKey.userType,
                  let managedObjectContext = decoder.userInfo[backgrounManagedObjectContext] as? NSManagedObjectContext,
                  let parentLogin:String = decoder.userInfo[parentLoginKey] as? String,
                  let userType:Int64 = decoder.userInfo[userTypeKey] as? Int64,
              let entity = NSEntityDescription.entity(forEntityName: "User", in: managedObjectContext) else {
                      fatalError("Failed to decode User")
              }
              let container = try decoder.container(keyedBy: CodingKeys.self)
              
              var existingUser:User?
              do {
                  let fetchRequest:NSFetchRequest = User.fetchRequest()
                  let predicate = NSPredicate(format: "login CONTAINS[cd] %@ and parentLogin CONTAINS[cd] %@ and userType == %d", try container.decodeIfPresent(String.self, forKey: .login) ?? "", parentLogin, userType)
                  fetchRequest.predicate = predicate
                  
                  let fetchResults = try managedObjectContext.fetch(fetchRequest)
                  
                  if (fetchResults.count > 0){
                      existingUser = fetchResults.first
                  }
                  
              } catch let error {
                  print(error)
              }
              // This is possible
              self.init(entity: entity, insertInto: managedObjectContext)
             // But we cannot do, self is immutable
             self = existingUser
      }
      

       

      So, currently we are inserting the values from core data to self object and then use the decoder container

       

      if existingUser != nil {
                  self.avatarURL = existingUser?.avatarURL
                  self.bio = existingUser?.bio
                  self.blog = existingUser?.blog
                  self.company = existingUser?.company
                  self.createdAt = existingUser?.createdAt
                  self.email = existingUser?.email
                  self.followers = existingUser?.followers ?? 0
                  self.followersURL = existingUser?.followersURL
                  self.following = existingUser?.following ?? 0
                  self.followingURL = existingUser?.followingURL
                  self.location = existingUser?.location
                  self.login = existingUser?.login
                  self.name = existingUser?.name
                  self.publicGists = existingUser?.publicGists ?? 0
                  self.publicRepos = existingUser?.publicRepos ?? 0
                  self.gistsURL = existingUser?.gistsURL
                  self.updatedAt = existingUser?.updatedAt
                  self.url = existingUser?.url
                  self.parentLogin = existingUser?.parentLogin
                  self.userType = existingUser?.userType ?? 1
                  
                  managedObjectContext.delete(existingUser!)
              }
              
              self.avatarURL = try container.decodeIfPresent(String.self, forKey: .avatarURL)
              self.bio = try container.decodeIfPresent(String.self, forKey: .bio)
              self.blog = try container.decodeIfPresent(String.self, forKey: .blog)
              self.company = try container.decodeIfPresent(String.self, forKey: .company)
              self.createdAt = try container.decodeIfPresent(Date.self, forKey: .createdAt)
              self.email = try container.decodeIfPresent(String.self, forKey: .email)
              self.followers = try container.decodeIfPresent(Int64.self, forKey: .followers) ?? 0
              self.followersURL = try container.decodeIfPresent(String.self, forKey: .followersURL)
              self.following = try container.decodeIfPresent(Int64.self, forKey: .following) ?? 0
              self.followingURL = try container.decodeIfPresent(String.self, forKey: .followingURL)
              self.location = try container.decodeIfPresent(String.self, forKey: .location)
              self.login = try container.decodeIfPresent(String.self, forKey: .login)
              self.name = try container.decodeIfPresent(String.self, forKey: .name)
              self.publicGists = try container.decodeIfPresent(Int64.self, forKey: .publicGists) ?? 0
              self.publicRepos = try container.decodeIfPresent(Int64.self, forKey: .publicRepos) ?? 0
              self.gistsURL = try container.decodeIfPresent(String.self, forKey: .gistsURL)
              self.updatedAt = try container.decodeIfPresent(Date.self, forKey: .updatedAt)
              self.url = try container.decodeIfPresent(String.self, forKey: .url)
              self.parentLogin = parentLogin
              self.userType = userType
      

       

      Attaching all the core data files for review.User+CoderDecoder.swift

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              ankitthakur85 Ankit Thakur
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: