앱 내 데이터 JSON으로 변환하기

오늘은 지금까지 수집한 데이터를 JSON 파일로 변환시켜 서버로 보내는 방식에 대해서 기록해두려고 한다 🙂

 

iOS 에서는 앱 내 데이터를 JSON 파일로 변환시켜 파일을 관리 할 수 있도록 지원하고 있다. 주로 JSONEncoder와 JSONDecoder를 사용해서 데이터를 JSON으로 변환하거나 JSON을 Swift객체로 변환할 수 있도록 잘 구현되어있다.

 

https://developer.apple.com/documentation/foundation/jsonencoder/

 

이때 데이터 모델은 Codable 프로토콜을 준수해야하고 이 안에 Encodable , Decodable 프로토콜을 포함하고 있다!

 

그렇기 때문에 이전에 구현해 둔 데이터 모델에 해당 프로토콜을 추가해주도록 하자!

// MARK: - Gps Model
struct Gps: Encodable, Identifiable {
    let id = UUID()
    var timeStamp: String
    var latitude: Float
    var longitude: Float
    var altitude: Float
}

해당 데이터 모델에 Encodable 프토토콜을 추가해주면서 JSONEncoder를 사용해 데이터를 JSON 데이터로 변환할 수 있게 된다.

 

그 다음 데이터를 우선 받아와야 해당 데이터를 변환할 수 있기 때문에 이전에 구현해두었던 데이터를 가져오는 로직을 활용해 앱에서 Gps 정보를 받아오도록 한다.

func saveLocationData(_ location: CLLocation) {
    let gpsData = Gps(
        timeStamp: location.timestamp.toString(),
        latitude: Float(location.coordinate.latitude),
        longitude: Float(location.coordinate.longitude),
        altitude: Float(location.altitude)
    )
    
    if let lastLocation = lastSavedLocation,
       lastLocation.latitude == gpsData.latitude,
       lastLocation.longitude == gpsData.longitude,
       lastLocation.altitude == gpsData.altitude {
        print("중복 데이터로 저장하지 않음")
        return
    }
    
    DispatchQueue.main.async {
        self.gpsDataList.append(gpsData)
        self.lastGpsEventDate = location.timestamp.toReadableString()
        self.lastSavedLocation = gpsData
        print("GPS 업데이트: \\(self.lastGpsEventDate)")
    }
    
    locationManager.stopUpdatingLocation()
}

이 함수는 새로운 GPS 데이터를 수집한 후 gpsDataList에 추가한다. 별도로 중복된 데이터는 저장하지 않도록 했다.

 

그 다음 CustomFileManager를 구현해 해당 매니저 내 Encodable 프로토콜을 준수하는 데이터를 인코딩할 수 있도록 로직을 구현했다.

func saveDataToJsonFile<T: Encodable>(data: T) {
    let jsonEncoder = JSONEncoder()
    jsonEncoder.outputFormatting = [.prettyPrinted, .sortedKeys]
    
    if let fileURL = getFileURL() {
        do {
            let encodedData = try jsonEncoder.encode(data)
            try encodedData.write(to: fileURL)
            print("데이터가 성공적으로 \\(fileURL.path)에 저장되었습니다.")
        } catch {
            print("JSON 파일 저장 중 오류 발생: \\(error.localizedDescription)")
        }
    } else {
        print("유효한 파일 경로를 찾을 수 없습니다.")
    }
}

JSONEncoder를 활용해 포멧 형식을 만들고 현재 저장된 데이터를 대입해 JSON 데이터로 변환할 수 있다.

func saveGpsDataToJSON() {
    CustomFileManager.gps.saveDataToJsonFile(data: gpsDataList)
    print("GPS 데이터를 JSON 파일로 저장 완료")
    
    // 저장 후 리스트 초기화
    gpsDataList.removeAll()
}

CustomFileManager에서 구현한 saveDataToJsonFile 메서드를 활용해 현재 앱에 수집된 데이터를 JSON 파일로 저장 후 기존 리스트는 초기화 시킨다.

func uploadGpsDataToServer() {
    guard let fileURL = CustomFileManager.gps.fileURL else {
        print("GPS 데이터 파일 경로를 찾을 수 없습니다.")
        return
    }
    
    APIClient.uploadCollectedFile(userPIN: CustomFileManager.gps.pinNumber, field: CustomFileManager.gps.field, fileUrl: fileURL)
        .sink { completion in
            switch completion {
            case .finished:
                // 업로드 성공 시 파일 삭제
                CustomFileManager.gps.deleteSentFile()
                print("GPS 데이터 파일 업로드 완료 후 삭제")
                
            case .failure(let error):
                print("GPS 데이터 파일 업로드 실패: \\(error.localizedDescription)")
            }
        } receiveValue: { response in
            print("서버 응답: \\(response)")
        }
        .store(in: &cancellables)
}

그 다음 저장된 JSON 파일을 서버로 업로드 하는 과정을 구현한다. 이를 위해 APIClient의 uploadCollectedFile 메서드를 활용한다.

 

CustomFileManager.gps.fileURL을 통해 저장된 JSON 파일의 경로를 확인하고

APIClient.uploadCollectedFile을 통해 해당 파일을 서버로 업로드한다.

 

업로드가 완료되면 CustomFileManager.gps.deleteSentFile()을 호출해 파일을 삭제한다.

 

이 방법을 활용하면 앱에 있는 데이터를 JSON 형태로 변환하여 데이터를 서버로 보낼 수 있도록 하는 과정이 완료된다!

 

앞으로 지금까지 수집한 이용자의 생체데이터를 JSON 파일로 변환해 firebase 내 저장하고 해당 데이터를 분석해 이용자에게 양질의 서비스를 제공할 수 있도록 데이터를 분석할 예정이다.

 

오늘은 데이터를 활용해 JSON 데이터로 변환하는 과정을 기록했다!

 

 

오늘은 여기까지!!!