4

enter image description here

This is my model class

class UserRoot : Mappable {
    var success : Bool!
    var user : UserDetails!
    var error = ""

    required init?(map: Map) {

    }
    func mapping(map: Map) {
        success <- map["success"]
        user <- map["user"]
        error <- map["error"]

    }
}

after successfully login i want to save this data on user defaults so that when a user have to not give login credential again. Here is my code

class Default : NSObject{
    static func saveToSharedPrefs(user: UserDetails!) {
        let d = UserDefaults.standard
        if user != nil {
            d.set(Mapper().toJSONString(user, prettyPrint: false) , forKey: "USERDETAILS")
        } else {
            d.set(nil, forKey: "USERDETAILS")
        }
        d.synchronize()
    }
}
AshvinGudaliya
  • 3,234
  • 19
  • 37
Gorib Developer
  • 587
  • 2
  • 13
  • 27
  • What is `Mappable`? Based on a little searching,it looks like there are a couple of different third party frameworks that use that protcol/class name. Whenever you use a third party framework you should include its name in your question title so others who have knowledge of that framework see the question and are more likely to read/answer it. – Duncan C Mar 29 '18 at 12:34
  • 1
    Note that you shouldn't store large/complex data into `UserDefaults`. It's meant for small bits of user settings. You could easily write your data to a plist in the documents directory, which would be a better way to do it. – Duncan C Mar 29 '18 at 12:38
  • Okay sir thanks for your valuable advise will keep it in my mind. – Gorib Developer Mar 29 '18 at 12:40
  • i can save the total userlist in plist sir? @DuncanC – Gorib Developer Mar 29 '18 at 12:44

4 Answers4

3

Make sure your model class is inherited from NSObject class otherwise it will crash at run time.

To store data:

let data = NSKeyedArchiver.archivedData(withRootObject: <Your model class>)
UserDefaults.standard.set(data, forKey: "userDetails")

To retrive and convert data back

if let data = UserDefaults.standard.value(forKey: "userDetails") as? Data {
    if let dict = NSKeyedUnarchiver.unarchiveObject(with: data) as? <Your model class> {
           print(dict)
     }
}
Mahendra
  • 8,448
  • 3
  • 33
  • 56
3

In swift 4 Better use JSONEncoder to encode your Swift object to JSON and JSONDecoder to decode your JSON to Swift object, Confirm Codable protocol to your Model class before encode and decode. You can follow this answer from stack overflow

  • sir no idea about codable – Gorib Developer Mar 29 '18 at 12:18
  • Start learning and using it, it will save your time and effort of JSON parsing. It is very easy to learn and implement. [Everything about Codable in Swift 4](https://hackernoon.com/everything-about-codable-in-swift-4-97d0e18a2999), [Painless JSON Parsing with Swift Codable](https://medium.com/xcblog/painless-json-parsing-with-swift-codable-2c0beaeb21c1) – Kazi Abdullah Al Mamun Mar 29 '18 at 12:25
  • Okay sir @Kazi Abdullah Al Mamun – Gorib Developer Mar 29 '18 at 12:26
  • 2
    I agree with Kazi. Swift 4 includes built-in support for mapping your object graph back and forth to JSON. If you do a Google search on "Swift 4 Codable" you'll find several pages of tutorials. Ray Wenderlich's site usually has good content. Try this one, for example: https://www.raywenderlich.com/172145/encoding-decoding-and-serialization-in-swift-4 – Duncan C Mar 29 '18 at 12:37
  • Okay sir @DuncanC – Gorib Developer Mar 30 '18 at 04:27
1

You can use Data to store this json in the user defaults like this:

let myData = NSKeyedArchiver.archivedData(withRootObject: myJson)
UserDefaults.standard.set(myData, forKey: "userJson")

let recovedUserJsonData = UserDefaults.standard.object(forKey: "userJson")
let recovedUserJson = NSKeyedUnarchiver.unarchiveObject(with: recovedUserJsonData)

Edit

you can not store mapper in NSUserDefault, you can only store NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary.

NSKeyedArchiver converts your mapper into NSData which you can store into userdefault.

Ramon Vasconcelos
  • 1,466
  • 1
  • 21
  • 28
0

Using ObjectMapper pod.

class GooglePlace : Mappable {

    var id = ""
    var addressTitle = ""
    var formattedAddress = ""
    var latitude : Double?
    var longitude : Double?

 required init?(map: Map) {

    }

    func mapping(map: Map) {
        addressTitle <- map["name"]
        formattedAddress <- map["formatted_address"]
        latitude <- map["geometry.location.lat"]
        longitude <- map["geometry.location.lng"]
        id <- map["id"]
    }

}

var placesesSearchHistory : [GooglePlace]? = []

if let jsonString = placesesSearchHistory?.toJSONString(prettyPrint: true) {
//Store in UserDefaults
      UserDefaults.standard.set(jsonString, forKey: "addressSearchHistory")

} 


//retrieve from UserDefaults
 if let dataArrayString = (UserDefaults.standard.string(forKey: "addressSearchHistory")) as? String {

 if let dataObject = Mapper<GooglePlace>().mapArray(JSONString: dataArrayString)  {
                placesesSearchHistory = dataObject
            }
        }
Pramod More
  • 1,220
  • 2
  • 22
  • 51
  • In Swift 4+ all third-party JSON parsing libraries have become obsolete in favor of built-in `Codable` protocol. And `string(forKey` **does** return an optional string, the conditional *downcast* is redundant. – vadian Feb 05 '19 at 14:43