๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“ ๊ธฐ๋ก/Trouble Shooting

[iOS/Trouble Shooting] ์—๋Ÿฌ์ฒ˜๋ฆฌ ์ž˜๋ชปํ•ด์„œ DB ๋‚ ๋ฆฐ ์ฐ

์•ˆ๋…•ํ•˜์„ธ์š” ์ œ์ธ์ž…๋‹ˆ๋‹ค :)

๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ๊ธฐ์กด์— ๊ณต๋ถ€ํ–ˆ๋˜ ๊ธฐ์ˆ ๋“ค์„ ํ•˜๋‚˜์”ฉ ์ ์šฉํ•ด๋ณด๊ณ  ์ถ”๊ฐ€๋กœ ๊ณต๋ถ€ํ•˜๊ณ  ์žˆ๋Š”๋ฐ์š”!

์ด๋ฒˆ ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ๊ฒช์€ ๋ฌธ์ œ๋ฅผ ํ•˜๋‚˜ ๊ณต์œ ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

์‹œ์ž‘ํ•˜๊ธฐ ์ „, ํ•ด๋‹น ๋ฌธ์ œ๋Š” ํœด๋จผ์—๋Ÿฌ์— ์˜ํ•ด ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์˜€๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๊ฒฐ ๊ณผ์ •์—์„œ ์–ด๋–ค ๋Œ€๋‹จํ•œ ๊ธฐ์ˆ ์„ ๊ณต๋ถ€ํ•˜๊ณ  ์ ์šฉํ•œ ๊ฒฝํ—˜์„ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒŒ์‹œ๊ธ€์ด ์•„๋‹™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์‹ค์ˆ˜๋กœ ์ž˜๋ชป ์ ์€ ์ฝ”๋“œ ํ•œ์ค„์ด ์–ผ๋งˆ๋‚˜ ํฐ ๊ฒฐ๊ณผ๋ฅผ ๋ถˆ๋Ÿฌ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๊นจ๋‹ฌ์•˜๋˜ ๊ฒฝํ—˜์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๊ณต์œ ํ•˜๊ณ  ๋˜ ํ•ด๊ฒฐ ๊ณผ์ •์—์„œ ์–ด๋–ป๊ฒŒ ๋ฌธ์ œ ๋ถ€๋ถ„์„ ์ฐพ์•„๋ƒˆ๋Š”์ง€ ๋””๋ฒ„๊น… ๋ฐฉ๋ฒ•์„ ๊ณต์œ ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค! 

์ฝ”๋“œ ํ•œ ์ค„ ์ž˜๋ชป์ ์—ˆ๋‹ค๊ฐ€ DB๋ฅผ ๋‚ ๋ ค๋ฒ„๋ ธ๋‹ค..!

๊ต‰์žฅํžˆ ์ž๊ทน์ ์ธ ํƒ€์ดํ‹€.. ํ•˜์ง€๋งŒ ์‹คํ™”์ž…๋‹ˆ๋‹ค๐Ÿ’ฅ

์‚ฌ๊ฑด์˜ ๋ฐœ๋‹จ์€ ํด๋ฆฐ ์•„ํ‚คํ…์ฒ˜ ๊ธฐ๋ฐ˜์˜ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ ๋ ˆ์ด์–ด์˜ ์—ญํ• ์„ ๋ช…ํ™•ํžˆ ํ•˜๊ณ  ๊ฐ์ฒด์˜ ์ฑ…์ž„์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์žฅ๊ธฐ์ ์ธ ๊ด€์ ์—์„œ ์ฝ”๋“œ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์‹œ์ž‘ํ•œ ๋„คํŠธ์›Œํ‚น ์ฝ”๋“œ ์ „์ฒด ๋ฆฌํŒฉํ† ๋ง์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด ๋„คํŠธ์›Œํ‚น ์ฝ”๋“œ ์ „์ฒด๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๋Š” ๋‚˜๋ฆ„ ๋Œ€๊ทœ๋ชจ ๊ณต์‚ฌ์˜€๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ ์ˆ˜์ •์ด ์ƒ๊ธฐ๋Š” ํŒŒ์ผ์ด ๋งŽ๊ณ , ๋น„์Šทํ•œ ๊ตฌ์กฐ์˜ ๋ฉ”์„œ๋“œ๋„ ๋งŽ์•˜์–ด์š”.

๊ทธ๋ž˜์„œ ์ฝ”๋“œ ํ•œ ์ค„์„ ์ž˜๋ชป ์ ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.. ๋ฌธ์ œ๊ฐ€ ๋œ ์ฝ”๋“œ์™€ ํ•ด๊ฒฐ ํ›„์˜ ์ฝ”๋“œ๋ฅผ ํ•จ๊ป˜ ๋ณด์‹œ์ ธ..

๋ฌธ์ œ์˜ ์ฝ”๋“œ

   // UserRepositoryImpl
   func fetchUserData(userId: String) -> AnyPublisher<UserEntity, NetworkError> {
        service.fetch(key: dbKey, path: userId)
            .mapError { _ in NetworkError.serverError}
            .flatMap { value in
                if let value {
                    return Just(value)
                        .tryMap { try JSONSerialization.data(withJSONObject: $0) }
                        .decode(type: UserDTO.self, decoder: JSONDecoder())
                        .map { $0.toEntity() }
                        .mapError { _ in NetworkError.serverError }
                        .eraseToAnyPublisher()
                } else {
                    return Empty().eraseToAnyPublisher()
                }
            }
            .eraseToAnyPublisher()
    }

์ˆ˜์ • ํ›„ ์ฝ”๋“œ

   // UserRepositoryImpl
   func fetchUserData(userId: String) -> AnyPublisher<UserEntity, NetworkError> {
        service.fetch(key: dbKey, path: userId)
            .mapError { _ in NetworkError.serverError}
            .flatMap { value in
                if let value {
                    return Just(value)
                        .tryMap { try JSONSerialization.data(withJSONObject: $0) }
                        .decode(type: UserDTO.self, decoder: JSONDecoder())
                        .map { $0.toEntity() }
                        .mapError { _ in NetworkError.serverError }
                        .eraseToAnyPublisher()
                } else {
                    return Fail(error: NetworkError.invalidURL).eraseToAnyPublisher()
                }
            }
            .eraseToAnyPublisher()
    }

 

์ˆ˜์ • ์ „ํ›„ ์ฝ”๋“œ์˜ ์ฐจ์ด๋Š” ์‚ฌ์‹ค ํ•œ์ค„ ๋ฐ–์— ๋˜์ง€ ์•Š๋Š”๋ฐ์š”,

์ฝ”๋“œ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•ด๋ณด์ž๋ฉด, ์‹ค์ œ ๋„คํŠธ์›Œํ‚น์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฐ์ฒด์ธ service์˜ fetch ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด DB์˜ ์œ ์ €๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. fetch์— successํ•˜๊ฒŒ ๋˜๋ฉด ๋ฐ›์•„์˜ค๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ DTO?(์˜ต์…”๋„) ํƒ€์ž…์ด์ง€๋งŒ Entity๋กœ ๋งคํ•‘์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ if let์„ ํ†ตํ•ด์„œ ์˜ต์…”๋„ ๋ฐ”์ธ๋”ฉ์„ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ๊ฐ’์ด ์žˆ๋‹ค๋ฉด Entity๋กœ ๋งคํ•‘ํ•ด Publish ํ•˜๊ณ , ๊ฐ’์ด nil์ด๋ผ๋ฉด fetch error์™€ ๊ฐ™์ด ๊ฐ„์ฃผํ•˜์—ฌ Fail์„ ๋ฐฉ์ถœํ•ด์ค๋‹ˆ๋‹ค.

 

์›๋ž˜์˜ ์˜๋„๋Š” ์œ„์™€ ๊ฐ™์•˜์œผ๋‚˜, ์ˆ˜์ • ์ „ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด if let else ๊ตฌ๋ฌธ์—์„œ Fail์ด ์•„๋‹Œ Empty Publisher๋ฅผ ๋ฐฉ์ถœํ•ด์ฃผ๊ณ  ์žˆ์ฃ .. ์˜ˆ์˜ˆ.. ์‹ค์ˆ˜๋ฅผ ํ•ด๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค.. 

๋ฌธ์ œ ์ƒํ™ฉ

์ฝ”๋“œ ํ•œ์ค„์˜ ์‹ค์ˆ˜๊ฐ€ ๋ถˆ๋Ÿฌ์˜จ ๋ฌธ์ œ๋Š” ํšŒ์› ํƒˆํ‡ด ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ์ฝ”๋“œ ์‹คํ–‰ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ๋ฐ›๊ฒŒ ๋˜๋Š” ์ฝ”๋“œ๋ฅผ ๋จผ์ € ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

final class DeleteAccountUseCaseImpl: DeleteAccountUseCase {
    private let userRepository: UserRepository
    
    init(userRepository: UserRepository) {
        self.userRepository = userRepository
    }
    
    func execute() -> AnyPublisher<Void, NetworkError> {
        userRepository.deleteUserData(userId: UserDefaults.userId)
            .mapError{ _ in
                return .serverError
            }
            .eraseToAnyPublisher()
    }
}

 

์œ ์ €๊ฐ€ ๊ณ„์ •์„ ์‚ญ์ œํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ, DB์˜ ์œ ์ € ๋ฐ์ดํ„ฐ ๋˜ํ•œ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ญ์ œํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋•Œ, ์‚ญ์ œํ•  ์ •๋ณด์˜ ๊ฒฝ๋กœ๋Š” https://luckyvicky์–ด์ฉŒ๊ตฌ์ €์ฉŒ๊ตฌ/Users/์œ ์ €์•„์ด๋”” ์˜ ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.

์œ ์ €๊ฐ€ ํƒˆํ‡ดํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด deleteAccount ๋กœ์ง์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๊ณ , UserDefaults์— ์ €์žฅ๋˜์–ด์žˆ๋Š” ์œ ์ €์•„์ด๋”” ๊ฐ’์„ ์ฐพ์•„์„œ ํ•ด๋‹น ๊ฒฝ๋กœ ํ•˜์œ„์— ์žˆ๋Š” ์œ ์ €์ •๋ณด๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ DB์˜ ์ •๋ณด๊ฐ€ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, UserDefaults์˜ ๊ฐ’์€ ์œ„์˜ fetchData์˜ ๊ฒฐ๊ณผ ๊ฐ’์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค.

extension LoginViewModel {
    
    private func login(_ result: Result<ASAuthorization, Error>) {
        ...
        useCase.executeSignIn(authorization, nonce: nonce)
            .sink { [weak self] completion in
                if case .failure(_) = completion {
                    self?.state.hasErrorOccurred = true
                }
                self?.state.isLoading = false
            } receiveValue: { [weak self] user in
                UserDefaults.userId = user.id
                UserDefaults.usedCount = user.usedCount
                UserDefaults.isFirstLaunch = false
                self?.coordinator.present(sheet: .selectCharacter)
            }.store(in: &cancellables)
        ...
    }
}

 

์œ„์˜ ์ฝ”๋“œ๋Š” ๋กœ๊ทธ์ธ ๋กœ์ง์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. executeSignIn์„ ํ˜ธ์ถœํ•˜๋ฉด authentication ์ƒํƒœ์— ๋”ฐ๋ผ ๋กœ๊ทธ์ธ ๋˜๋Š” ํšŒ์›๊ฐ€์ž…์„ ์‹œํ‚ค๊ณ ,

์œ„์—์„œ ๋ดค๋˜ fetchUserData ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ดˆ๊ธฐ ์œ ์ €์ •๋ณด๋ฅผ UserDefaults์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. (๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ)

์ฆ‰, ๋กœ๊ทธ์ธ ๋กœ์ง์— fetchUserData ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ด์ฃ .

 

์œ„์˜ ์ฝ”๋“œ์—์„œ receiveValue ๊ตฌ๋ฌธ์—์„œ๋งŒ UserDefaults์— ๊ฐ’์„ ์„ธํŒ…ํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” ๋กœ๊ทธ์ธ์— ์„ฑ๊ณต ํ•  ๊ฒฝ์šฐ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์ดํ›„ ๋กœ์ง์„ ์‹คํ–‰ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ ๊ณผ์ •(authentication ์ฒดํฌ - ์• ํ”Œ์—์„œ ๊ถŒํ•œ ์œ„์ž„ - idToken๋ฐœ๊ธ‰ - ํšŒ์›๊ฐ€์ž…/๋กœ๊ทธ์ธ - DB๋ฐ์ดํ„ฐ fetch) ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•  ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋Œ€์‹ , ์œ ์ €๊ฐ€ ๋กœ๊ทธ์ธ์„ ์žฌ์‹œ๋„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์•ˆ๋‚ด๋ฅผ ํ•ด์•ผ๊ฒ ์ฃ .

   // UserRepositoryImpl
   func fetchUserData(userId: String) -> AnyPublisher<UserEntity, NetworkError> {
        service.fetch(key: dbKey, path: userId)
            .mapError { _ in NetworkError.serverError}
            .flatMap { value in
                if let value {
                    return Just(value)
                        .tryMap { try JSONSerialization.data(withJSONObject: $0) }
                        .decode(type: UserDTO.self, decoder: JSONDecoder())
                        .map { $0.toEntity() }
                        .mapError { _ in NetworkError.serverError }
                        .eraseToAnyPublisher()
                } else {
                    return Empty().eraseToAnyPublisher()
                }
            }
            .eraseToAnyPublisher()
    }

 

์œ„์—์„œ ์‹ค์ˆ˜ํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์™€๋ณผ๊ฒŒ์š”.

์ €๋Š” ๋กœ๊ทธ์ธ ๊ณผ์ • ์ค‘ ํ•˜๋‚˜์ธ fetchUserData์— ์‹คํŒจํ•  ๊ฒฝ์šฐ Error ๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ Empty๋ผ๋Š” ๋นˆ ๊ฐ’์„ ๋ฐฉ์ถœํ•ด ์„ฑ๊ณต ์ผ€์ด์Šค๋กœ ๋„˜๊ฒจ๋ฒ„๋ฆฐ ๊ฒƒ์ž…๋‹ˆ๋‹ค. 

์ด๋ ‡๊ฒŒ ๋˜๋ฉด, UserDefaults์— UserId ๊ฐ’์ด "" ์ด๋Ÿฐ์‹์œผ๋กœ ๋นˆ ๊ฐ’์ด ์ €์žฅ๋˜๊ณ , ์ด ํ›„ ๊ณ„์ • ์‚ญ์ œ๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด https://luckyvicky์–ด์ฉŒ๊ตฌ์ €์ฉŒ๊ตฌ/Users/"" ์ด๋ ‡๊ฒŒ ์œ ์ €์•„์ด๋”” ๊ฐ’์ด ๋“ค์–ด๊ฐ€์•ผ ํ•  ์ž๋ฆฌ์— ๋นˆ ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜์–ด Users ํ•˜์œ„์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•ด์ค˜! ํ•˜๊ณ  ์š”์ฒญํ•˜๋Š” ํฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด์ฃ ..

 

DB ์‹น ์žƒ์€ ๋‚˜.. ๋ง‰์ด๋ž˜..

๋””๋ฒ„๊น… ๋ฐฉ๋ฒ•

์ผ๋‹จ ๋””๋ฒ„๊น… ์ดํ›„ ์ฐพ์€ ๋ฌธ์ œ ์›์ธ๋ถ€ํ„ฐ ์„ค๋ช…๋“œ๋ ธ๋Š”๋ฐ์š”, ๊ทธ๋Ÿฌ๋ฉด ์ด ๋ถ€๋ถ„์ด ๋ฌธ์ œ๋ผ๋Š” ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์ฐพ์•˜๋ƒ?

๋ฐ”๋กœ๋ฐ”๋กœ lldb๋ฅผ ์ด์šฉํ•œ ๋นˆํ‹ˆ์—†๋Š” ๋””๋ฒ„๊น….. ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋จผ์ €, ์ด๋ ‡๊ฒŒ ์˜ˆ์ƒ ์‹คํ–‰ ์ˆœ์„œ๋Œ€๋กœ Breakpoint๋ฅผ ์ฐ์–ด์ค๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋ฉด, ์ด๋Ÿฐ ์‹์œผ๋กœ ์‹ค์ œ๋กœ ์‹คํ–‰๋˜๋Š” ์ˆœ์„œ๋Œ€๋กœ breakpoint์— ๊ฑธ๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ, ์ฐ์–ด๋†“์€ breakpoint์— ๋ชจ๋‘ ๊ฑธ๋ฆฌ์ง€ ์•Š๊ณ  ์ข…๋ฃŒ๋˜๋ฉด, ์ค‘๊ฐ„์— ํ˜ธ์ถœ์ด ๋Š๊ธด ๊ฒƒ์ด๋‹ˆ, ๋Š๊ธด ์ง€์ ์„ ์ฐพ์•„์„œ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ค‘๊ฐ„์ค‘๊ฐ„ ์‹ค์ œ๋กœ ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ด๊ธฐ๋‚˜? ํ™•์ธํ•ด๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด lldb์˜ po ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

po ๋ช…๋ น์–ด๋ฅผ ํ™œ์šฉํ•œ ๋ฐ์ดํ„ฐ ํ™•์ธ

์ด๋ ‡๊ฒŒ breakpoint๊ฐ€ ๊ฑธ๋ฆฌ๋Š” ๋ผ์ธ์—์„œ path์— ๋‹ด๊ธด ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด po path๋ฅผ ์ž…๋ ฅํ•˜๊ฒŒ ๋˜๋ฉด ๊ฐ’์ด ๋””๋ฒ„๊น… ์ฐฝ์— ๋‚˜์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ €์˜ ๊ฒฝ์šฐ, ์ด ๊ณผ์ •์—์„œ path์˜ ๊ฒฐ๊ณผ๊ฐ€ Users/ ๋กœ ๋‚˜์˜ค๊ฒŒ ๋˜์–ด์„œ ์˜ˆ์ƒ ๊ฐ’์ด ์•ˆ๋‚˜์˜ค๋„ค? UserId ๊ฐ’์ด UserDefaults์— ์ €์žฅ๋˜๋Š” ๊ณผ์ •์„ ๋””๋ฒ„๊น…ํ•ด๋ด์•ผ์ง€! ์˜ ํ๋ฆ„์œผ๋กœ ๋””๋ฒ„๊น…์„ ํ•ด์„œ ๋ฌธ์ œ ์›์ธ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

DB ๋ณต๊ตฌ ๋ฐฉ๋ฒ•

๊ทธ๋ ‡๋‹ค๋ฉด.. DB ๋ณต๊ตฌ๋Š” ์–ด๋–ป๊ฒŒ ํ•˜์…จ์–ด์š”?? 

์— ๋Œ€ํ•œ ๋Œ€๋‹ต์€.. ์ˆ˜๋™์œผ๋กœ ํ•˜๊ธด ํ–ˆ์Šต๋‹ˆ๋‹ค.. ใ…Žใ…Ž

ํ•˜์ง€๋งŒ..! Json ํ˜•์‹์œผ๋กœ ๋น ๋ฅด๊ฒŒ ์ž‘์„ฑํ•ด์„œ DB์— ๋ฐ˜์˜ํ•ด์ฃผ๊ธด ํ–ˆ์Šต๋‹ˆ๋‹ค ..

์ €๋Š” Firebase์˜ Realtime Database๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ์š”(๋ฐ์ดํ„ฐ๊ฐ€ id๊ฐ’, ์œ ์ €๋ณ„ ํ•˜๋ฃจ ์‚ฌ์šฉํšŸ์ˆ˜๋กœ ๊ฐ„๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์—),

์†Œ์…œ๋กœ๊ทธ์ธ๋„ FirebaseAuth๋ฅผ ์ด์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ •๋ณด์ธ UserId๊ฐ’์„ ์ฐพ์•„์„œ ๋ณต๊ตฌ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

Firebase์˜ Authentication ํƒญ์œผ๋กœ ๊ฐ€๋ฉด ์ด๋ ‡๊ฒŒ ๊ฐ€์ž…ํ•œ ์œ ์ €์˜ ์‚ฌ์šฉ์ž UID๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์ด์šฉํ•ด์„œ DB๋ฅผ ๋ณต๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ €์˜ ์„œ๋น„์Šค์˜ ๊ฒฝ์šฐ ํ•˜๋ฃจ๊ฐ€ ์ง€๋‚˜๋ฉด ์–ด์ฐจํ”ผ ์ดˆ๊ธฐํ™”๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํฐ ๋ฌธ์ œ์—†์ด ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ๊ธด ํ–ˆ์Šต๋‹ˆ๋‹ค.. ํ•˜์ง€๋งŒ.. ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ์˜€๋‹ค๋ฉด.. ๋งค์šฐ ์•„์ฐ”- ํ•˜๋„ค์š”.

๋Š๋‚€์ 

๋จผ์ €, ํ•œ ์ค„ ์ž˜๋ชป ์“ด ์ฝ”๋“œ๊ฐ€ ์ด๋ ‡๊ฒŒ ํฐ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ผˆ์ €๋ฆฌ๊ฒŒ ๋Š๊ผˆ์Šต๋‹ˆ๋‹ค..

๋˜ ์ค‘์š”ํ•œ ๊ฒƒ์€ debug๋ชจ๋“œ, release๋ชจ๋“œ๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ์‹ค์ œ db๋Š” ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ๋…๋ฆฝ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๊ฒ ๊ตฌ๋‚˜๋ฅผ ๋Š๊ผˆ์Šต๋‹ˆ๋‹ค.

(+ ํ˜น์‹œ๋‚˜ ๋ชจ๋ฅผ ์ƒํ™ฉ์— DB ๋ฐฑ์—…๋„ ์ฃผ๊ธฐ์ ์œผ๋กœ ํ•ด์•ผ๊ฒ ์Šต๋‹ˆ๋‹ค. )

 

์˜ค๋Š˜๋„ ๊ธด ๊ธ€ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค๐Ÿ€

ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…์˜ ์ฃผ์ธ๊ณต ๋Ÿญํ‚ค๋น„ํ‚ค ์„œ๋น„์Šค๋„ ๋‹ค์šด๋ฐ›์•„์ฃผ์„ธ์š”~ใ…Ž

 

‎๋Ÿญํ‚ค๋น„ํ‚ค - ๊ธฐ๋ถ„ ์ข‹์€ ์˜ค๋Š˜์„ ์œ„ํ•œ ์‚ฌ๊ณ  ๋ณ€ํ™˜๊ธฐ

‎์•ˆ๋…•ํ•˜์„ธ์š”, ๋Ÿญํ‚ค๋น„ํ‚ค ์„œ๋น„์Šค์— ์˜ค์‹  ์—ฌ๋Ÿฌ๋ถ„๋“ค์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ๋Ÿญํ‚ค๋น„ํ‚ค๋Š” ๊ฑธ๊ทธ๋ฃน ์•„์ด๋ธŒ(IVE)์˜ ๋ฉค๋ฒ„์ธ ์žฅ์›์˜์˜ ๊ธ์ •์ ์ธ ์‚ฌ๊ณ ๋ฐฉ์‹๊ณผ ํ™”๋ฒ•์—์„œ ๋น„๋กฏ๋œ ๋ฐˆ(Meme)์œผ๋กœ, ์–ด๋–ค ํž˜๋“  ์ƒํ™ฉ์—์„œ๋„ ํ–‰

apps.apple.com