1

I am building an app that will work with Plaid. Plaid provides a nice little LinkKit that I need to use to grab my link_token. I provide that link_token to authenticate to a bank. I have written a request using Alamofire to send the .post to get the new link_token when someone would want to add another account. My issue is when I decode the JSON to a struct that I have built I cant seem to use that stored link_token value.

Code to retrieve link_token

let parameters = PlaidAPIKeys(client_id: K.plaidCreds.client_id,
                              secret: K.plaidCreds.secret,
                              client_name: K.plaidCreds.client_name,
                              language: K.plaidCreds.language,
                              country_codes: [K.plaidCreds.country_codes],
                              user: [K.plaidCreds.client_user_id: K.plaidCreds.unique_user_id],
                              products: [K.plaidCreds.products])

func getLinkToken() {
    
    let linkTokenRequest = AF.request(K.plaidCreds.plaidLinkTokenURL,
                                      method: .post,
                                      parameters: parameters,
                                      encoder: JSONParameterEncoder.default).responseDecodable(of: GeneratedLinkToken.self) { response in
                                        print(response)
                                    }
                                    }

Struct I have built:

struct GeneratedLinkToken: Decodable {
    let expiration: String
    let linkToken: String
    let requestID: String
    
    enum CodingKeys: String, CodingKey {
       case expiration = "expiration"
       case linkToken = "link_token"
       case requestID = "request_id"
    }
}

I have tested by calling the function getLinkToken() when pressing my add account or dummy button, I do get the data back that I am needing. Why wouldnt I be able to access GeneratedLinkToken.linkToken directly after the request?

thetanis
  • 13
  • 3

1 Answers1

0

You aren't able to access linkToken property like this: GeneratedLinkToken.linkToken, because linkToken is as instance property(read here)

If you want to get an instance after your request, you can do it like this:

func getLinkToken(completion: @escaping ((GeneratedLinkToken) -> Void)) {
    let linkTokenRequest = AF.request(K.plaidCreds.plaidLinkTokenURL,
                                      method: .post,
                                      parameters: parameters,
                                      encoder: JSONParameterEncoder.default).responseDecodable(of: GeneratedLinkToken.self) { response in
                                        print(response)

                                        // if response is an object of type GeneratedLinkToken
                                        switch response.result {
                                        case .success(let object):
                                            completion(object)                                             
                                        case .failure(let error):
                                             // hanlde error
                                        }
                                    }
}

Later you can call as:

getLinkToken { linkObject in
    print("My tokne: \(linkObject.linkToken)")
}

I added completion(read here) to your method, since the request executing async, you can take a look at this Q/A: read here. I also suggest you, pass parameters as a parameter to this function, not declare it globally.

vpoltave
  • 1,612
  • 3
  • 14
  • 31
  • This makes a bit more sense. I thought I would need a completion but was unsure how to structure. Running this I get an error though: `Cannot convert value of type 'DataResponse' to expected argument type 'GeneratedLinkToken'` – thetanis Mar 07 '21 at 15:34
  • @thetanis I edited my answer, should work now – vpoltave Mar 07 '21 at 19:52
  • Alright, I get that switch statement now. I guess where I am failing from here is grasping how I assign that string value from `getLinkToken { linkObject in.....` to something else. That print returns the right value. I've tried assigning an empty value to a variable and then adding that value in to it. ``` let test = getLinkToken { object in var test1 = "" test1 = object.linkToken print(test1) } ``` but this isn't available to use outside this scope. Sorry, still learning here. – thetanis Mar 08 '21 at 20:22
  • @thetanis This looks like a different question, try to solve it yourself if you can't, just create another question, don't mix questions in question. – vpoltave Mar 08 '21 at 21:27