본문 바로가기
IOS - Swift

[iOS/Swift] accesstoken 저장이 안될때

by 게게겍 2023. 5. 21.

애플로그인 구현중 accesstoken 저장이 안되는 문제가 생겻습니다.

제가 진행하려는 상황은

 

💡 애플로그인 버튼을 눌럿을 때 서버에서 idtoken, refresh , access 토큰을 반환받음 → 반환받은 refresh,access 토큰을 userdefault에 저장하고 저장된 userdefault 를 이후 페이지에서 사용함


그러기 위해서는 userdefault에 코드를 저장하고 저장이 되어있다면 다음 페이지에서accessToken 을 사용하고자 하는 코드를 구현하는 중이엿습니다.

해당 동작중, if문이 동작하게 햇는데 자꾸 else로 탈출을 하는 경우였습니다.

 

 

실패 1


AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).validate().responseJSON { response in
               switch response.result {
                case .success:
                    if let data = response.data {
                        do {
                            if let jsonResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
                               let accessToken = jsonResponse["accessToken"] as? String {
                                UserDefaults.standard.set(accessToken, forKey: "accessToken")
                                completion(true) // Call completion handler here
                            }
                        } catch {
                            print("Error during JSON serialization: \\(error.localizedDescription)")
                            completion(false)
                        }
                    }
                case .failure(let error):
                    print("Error sending user info: \\(error)")
                    completion(false) 
               }
            }

처음에 시도햇던 코드입니다.if문 내에서 userdefault에 저장하고 completion으로 반환을 하려 하였으나 해당 문장에서 else문으로 탈출하게 됩니다.

 

 

실패 2


AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).validate().responseJSON { response in
            switch response.result {
            case .success:
                if let data = response.data {
                    do {
                        if let jsonResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                            print("Received JSON response: \\(jsonResponse)")
                            if let accessToken = jsonResponse["accessToken"] as? String, let idToken = jsonResponse["id_token"] as? String {
                                // Save the access token and id token to UserDefaults
                                UserDefaults.standard.set(accessToken, forKey: "accessToken")
                                UserDefaults.standard.set(idToken, forKey: "id_token")
                                UserDefaults.standard.synchronize() // Force the data to be saved right away
                                completion(true)
                            } else {
                                print("One or both tokens are missing in the server response.")
                                completion(false)
                            }
                        }
                    }
                    catch {
                        print("Error during JSON serialization: \\(error.localizedDescription)")
                        completion(false)
                    }
                }
            case .failure(let error):
                print("Error sending user info: \\(error)")
                completion(false)
            }
        }
    }

두번째로 시도했던 코드입니다.

Userdefault 에 id_token과 accessToken을 분리해서 저장햇습니다.

이렇게 하면 id_token은 성공적으로 저장이 되었으나(print 로 확인) accessToken으로 저장이 되지 않았습니다.

확실하게 사용하고자 synchronize 로 강제로 저장을 시도하였으나 결과는 동일하게 실패였습니다..

 

다시확인해보니 사용하지말라햇는데 굳이 왜 사용했던걸까요

 

 

 

성공~!


 AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).validate().responseJSON { response in
            switch response.result {
            case .success:
                if let data = response.data {
                    do {
                        if let jsonResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                            print("Received JSON response: \\(jsonResponse)")
                            if let accessToken = jsonResponse["accessToken"] as? String {
                                // Save the access token to UserDefaults
                                UserDefaults.standard.set(accessToken, forKey: "accessToken")
                                print("Access token saved to UserDefaults.")
                                print(accessToken)
                                
                            } else {
                                print("Access token is missing in the data dictionary.")
                            }
                        } else {
                            print("'data' dictionary is missing in the server response.")
                        }
                        completion(true)
                    } catch {
                        print("Error during JSON serialization: \\(error.localizedDescription)")
                        completion(false)
                    }
                }
            case .failure(let error):
                print("Error sending user info: \\(error)")
                completion(false)
            }
        }
    }

 

생각보다 멍청한 실수였습니다… 서버에서 받는 swagger를 다시보니

사용하려는곳(Nickname)이 data 딕셔너리에 한번에 묶여있어서 data 딕셔너리를 추출하고 그 다음 nickname으로 post를 해야 post를 보낼 수 있는것이였습니다.

 

결론:2중추출일수 있으니 스웨거를 잘 확인하자

 

 

추후 리팩토링을 한다면:

Response 타입이 data, message, code 세가지인데 이 세가지를 제네릭으로 관리하자!