웹에서 ios 를 활용하여 파일 업로드 하는 방법중
<input type='file' />
이 있다.
하지만 이 방법은 내가 원하는 기능의 쉬운 접근법은 될지 몰라도 완벽한 기능을 구현하지는 못하였다.
내가 원하는 기능은
1. 사진을 여러장 촬영 첨부할수 있을것.
2. 사진촬영, 사진첩 선택촬영 두가지 기능 모두 가능할것.
위 두가지가 모두 만족해야 했다. 하지만 1번에서 촬영한 사진을 첨부할경우 <input type='file' /> 을 여러개 사용하면 가능하지만.
안드로이드와 같은 페이지를 바라보게 설계된 나의 앱에서는 페이지의 뷰가 변경되어서 사용자에게 혼란을 줄수 있다고 판단하였다.
그래서 위의 기능을 모두 충족할 방법을 찾다가 ImagePickerController 를 swift에서 사용할수 있다는 정보를 얻어 구글링과 책을 찾아보았다.
먼저 나는 모든 기능을 ViewController에서 해결한다.(아직 기능도 많지않고.. swift초보라 어려움)
import MobileCoreServices
를 추가하여 헤더 파일을 import 한후
extension ViewController:UIImagePickerControllerDelegate,UINavigationControllerDelegate{
}
필자는 해당 기능을 extension으로 빼서 활용했으므로 extension 에 UIImagePickerControllerDelegate, UINavigationControllerDelegate 를 추가하였다.
func btnCaptureImageFromCamera(_ sender: Any) {
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
flagImageSave = true
imagePicker.delegate = self
imagePicker.sourceType = .camera
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Camera inaccessable", message: "Application cannot access the camera.")
}
}
func btnLoadImageFromLibrary(_ sender: Any) {
if (UIImagePickerController.isSourceTypeAvailable(.photoLibrary)) {
flagImageSave = false
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
imagePicker.mediaTypes = [kUTTypeImage as String]
imagePicker.allowsEditing = false
present(imagePicker, animated: true, completion: nil)
}
else {
myAlert("Photo album inaccessable", message: "Application cannot access the photo album.")
}
}
그리고 카메라 촬영과, 사진첩 불러오는 기능을 구현해주었다.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString
if mediaType.isEqual(to: kUTTypeImage as NSString as String) {
captureImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
if flagImageSave {
print("사진저장들어왔지요")
}
if (UIImagePickerController.isSourceTypeAvailable(.camera)) {
let imgName = UUID().uuidString+".jpeg"
let documentDirectory = NSTemporaryDirectory()
let localPath = documentDirectory.appending(imgName)
let data = captureImage.jpegData(compressionQuality: 0.3)! as NSData
data.write(toFile: localPath, atomically: true)
let photoURL = URL.init(fileURLWithPath: localPath)
//카메라로 촬영했을때 로직구현
}else if(UIImagePickerController.isSourceTypeAvailable(.photoLibrary)){
let imageUrl=info[UIImagePickerController.InfoKey.imageURL] as? NSURL
let imageName=imageUrl?.lastPathComponent//파일이름
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)//파일경로
let data=NSData(contentsOf: imageUrl as! URL)!
//사진첩(라이브러리)로 사진을 가져왔을때 로직구현
}
}
else if mediaType.isEqual(to: kUTTypeMovie as NSString as String) {
if flagImageSave {
}
}
self.dismiss(animated: true, completion: nil)
}
가장 중요한 부분인
사진을 선택했을때 앱에서 처리해주어야 할부분을 위와 같이 구현하였다.
사진첩으로 사진을 선택했을때와, 카메라로 사진을 촬영했을때 2가지로 나누어서 로직을 구현하였는데
이유는 카메라로 촬영하였을때 info[UIImagePickerController.InfoKey.imageUrl] 의 값이 nil로 반환되어 파일에 접근을 하지 못하였다.
(카메라로 촬영하였을때는 기기에 사진파일이 저장되지 않은 상태라 imageUrl의 추출이 안되는것으로 생각된다.)
그래서 카메라로 촬영하였을때는 임의 파일을 생성하여 내가 촬영한 이미지를 해당 파일에 임시로 할당하여 사진파일에 접근 가능하도록 구현하였다.