어느덧 졸업작품이 끝을 향해 달려가고 있다. 이번에는 서버에 사용자의 전신 사진을 보내면 서버에서 해당 사진을 바탕으로 딥러닝 모듈을 돌린 뒤 반환되는 obj 파일을 사용자에게 전달하는 것을 코드로 구현하였다. 동작을 간단하게 설명해보면 다음과 같다.
func getUserModel(_ image: UIImage, completion: @escaping () -> Void) {
let url = K.flaskURL + "createUserModel"
let headers: HTTPHeaders = ["Content-type": "multipart/form-data"]
AF.upload(multipartFormData: { multipart in
if let imageData = image.pngData() {
multipart.append(imageData, withName: "file", fileName: "\(UserInfo.shared.uid!).png", mimeType: "image/png")
}
// if let imageData = image.jpegData(compressionQuality: 1) {
// multipart.append(imageData, withName: "file", fileName: "k.jpg", mimeType: "image/jpeg")
// }
},
to: url,
method: .post,
headers: headers).responseJSON { response in
switch response.result {
case .success:
print("Success")
guard let result = response.data else { return }
do {
let decoder = JSONDecoder()
let json = try decoder.decode(SceneModel.self, from: result)
self.getTempUserModel(url: json.url)
completion()
} catch {
print("error!\(error)")
}
case .failure(let e):
print(e)
}
}
}
@app.route('/createUserModel', methods=['POST'])
def create_user_model():
# HTTP POST 방식으로 전송된 이미지 받기
f = request.files['file'] # 파일 받기
d = request.form # 데이터 받기
f.save("./user_images/" + secure_filename(f.filename))
# 사용자의 사진을 바탕으로 사용자 모델 생성 및 user_models에 저장
# 해당 파일을 반환
json_data = {
'url': "/downloadUserModel"
}
return jsonify(json_data)
# return send_file("./user_models/" + "temp_mesh.obj", mimetype='application/wavefront-obj')
@app.route('/downloadUserModel', methods=['GET'])
def download_user_model():
return send_file("./user_models/" + "temp_mesh.obj", mimetype='application/wavefront-obj')
가장 어려웠던 부분은 현재 내 프로젝트가 mvvm을 따르고 있는데(부분적으로..?) Service 쪽에서 값이 변경되었을 때 어떻게 하면 VC에서 변경된 순간에 set3DModel 함수를 불러올 수 있는지였다. 이 때 Observable을 이용하면 값이 바뀌었을 때 할 동작을 지정할 수 있다는 것을 알게 되었다. Observable에 대한 설명은 다음 포스팅에서 진행하고 우선은 obj 파일을 받아서 화면에 렌더링하는 코드를 알아보겠다.
let decoder = JSONDecoder()
let json = try decoder.decode(SceneModel.self, from: result)
self.getTempUserModel(url: json.url)
func getTempUserModel(url: String) {
let destinationPath: DownloadRequest.Destination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0];
let fileURL = documentsURL.appendingPathComponent("my_mesh.obj")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
let url = K.flaskURL + url
AF.download(url, to: destinationPath)
.downloadProgress { progress in
}
.responseData { response in
switch response.result {
case .success:
print("Success")
// self.userModelPath.value = self.getFilePathInDocuments(fileName: "my_mesh.obj")
self.userModelPath.value = response.fileURL
case .failure(let e):
print(e)
}
}
}