앱에서 컨텐츠를 만들 수 있는 중요한 기능 구현을 앞두고 있습니다.
리뷰를 업로드 한다면 이제 많인 데이터를 가공 할 준비가 될 것 같습니다. 리뷰들을 모아 평점을 계산한다던가
리뷰에 업로드한 이미지들을 모아 해당 맛집의 이미지 리스트로 보여준다던가.
앱을 리팩토링하면서 이날을 기다려왔던 것 같습니다.
그럼 구현해보도록 하겠습니다.
업로드에 주요한 기능중 하나는 멀티파트를 사용하는건데 위키를 통해 간단한 개념정도는 알고 있는게 좋을 것 같아 링크로 남겨두었습니다. Restful방식에서 정보를 전달하는 방식으로 MIME 유형을 사용하고 multipart message는 MIME의 데이터 설정 방법 중 하나 인 것 같습니다.
https://ko.wikipedia.org/wiki/MIME
뷰모델의 리뷰 업로드 함수
데이터는 일부는 아직 더미로 만들고 있지만 추후 변경 할 예정입니다. 데이터를 만들어 repository에 전달하는것이 뷰모델에서 업로드 함수가 하는 기능입니다.
/**
* 리뷰 업로드
*/
fun uploadReview() {
val reviewAndImage = ReviewAndImage(
FeedData(
userId = 4,
restaurant_id = 332,
contents = contents.value,
rating = rating.value
),
ArrayList<ReviewImage>().apply {
for (path in selectedImagePath.value!!)
add(ReviewImage(picture_url = path))
},
UserData(userId = 4)
)
viewModelScope.launch {
_isUploaded.postValue(true)
myReviewRepository.uploadReview(reviewAndImage)
_isUploaded.postValue(false)
}
}
repository에서 데이터 업로드 처리
multipart 메시지를 설정하여 retrofit service을 호출하여 업로드합니다.
override suspend fun uploadReview(review: ReviewAndImage) {
val fileList = ArrayList<File>()
for (image in review.images) {
fileList.add(File(image.picture_url))
}
val pictureList = ArrayList<MultipartBody.Part>()
Logger.d(fileList.size)
for (i in fileList.indices) {
val file: File = fileList.get(i)
val requestFile: CountingFileRequestBody =
CountingFileRequestBody(file, "image/*",
CountingFileRequestBody.ProgressListener { num: Long ->
val percentage = num.toFloat() / file.length().toFloat() * 100
/*if (onFileUploadProgressListener != null) {
onFileUploadProgressListener.OnProgress(file, percentage)
}*/
})
pictureList.add(MultipartBody.Part.createFormData("file", file.name, requestFile))
}
try {
getService().fileUpload(review.toMap(), pictureList)
} catch (e: Exception) {
Logger.e(e.toString())
}
}
업로드가 완료되면 최초화면으로 다시 진입해야 하는점이 있는데 이부분은 차차 진행하도록하겠습니다!