0

I am fetching user's data as json from a service and decoding into Codable User struct. I can access that property where I've fetched the response but I want to access that User struct property somewhere else, let's say in another class, function, etc.

I'm new to this and I'm thinking the ideal approach is to "at the time of fetching, store that data into Core Data or User Defaults and then update my views accordingly.

Please suggest what's the best and appropriate approach or wether there is any way to access codable struct values directly.

Here is my codable struct -

struct User: Codable {
let name : String?

enum CodingKeys: String, CodingKey {
    case name = "Name"
}

init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    name = try values.decodeIfPresent(String.self, forKey: .name)
  }
}

The wrong way I'm accessing struct in some function is -

UserInfo.CodingKeys.name.rawValue
//Output is the key string - 'Name'
2
  • Shouldn't you be accusing it using something like more like someReferenceToUser.name? Commented Oct 5, 2018 at 4:17
  • "but I want to access that User struct property somewhere else, let's say in another class, function, etc" so the reference to User needs to be available to those classes/functions. Either you need to pass it to those elements or make it globally available in some way ... although, I'd look at how you would do this by passing the reference. You might consider Realm, but that might be to heavy weight for what you want to achieve Commented Oct 5, 2018 at 4:19

2 Answers 2

2

I think static can help you

struct User: Codable {
 let name : String?

 private enum CodingKeys: String, CodingKey {
  case name = "Name"
 }
}

assume fetching data here

class FetchingClass{
  static var user: User?

 func fetchData(){
  //After Url request success
  do {
  //assign directly to static varibale user
  FetchingClass.user = try JSONDecoder().decode(User.self, from: data)
} catch _ {
   }
  }
}

use like this wherever you want without using coreData or UserDefaults

class AnotherClass{
 func anotherClassFunc(){
 //use if let or guard let
  if let user = FetchingClass.user{
  print(user.name)
 }
 //or
 if let FetchingClass.user != nil {
  print(FetchingClass.name)
  }
 }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You can try using a singleton reference

struct User: Codable {

    let name : String?

    enum CodingKeys: String, CodingKey {
        case name = "Name"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        name = try values.decodeIfPresent(String.self, forKey: .name)
        User.shared = self
    }
}

Create another class which hold the ref. of User

final class AppGlobalManager  {
       static let sharedInstance = AppGlobalManager()

       var currentUser: User? // Initialise it when user logged in   

       private init()

}

Then you can access any of the user data as

AppGlobalManager.sharedInstance.currentUser.name

7 Comments

Why are you creating shared instance ? as it can be directly accessed with refe.
@PrashantTukadiya with singleton you don't need to pass the reference and as its static you can access it anywhere in the app.
Yes but you should create separate class with shared instance , which has user ref object. with that you don't need to create Codable class shared instance inside the class Hope you get my point
@PrashantTukadiya That is totally a personal choice and also depends on what architecture you are using for the app. I like to keep my model classes minimum so I only create pure model classes for my parsers and protocols for my view classes
You are correct that is personal choice. but for me it seems to be bad practice to have shared instance inside the codable class and may be hard to manage in future update or when the size of project is increased. but if we can keep all at one place that can be easy to manage.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.