새싹

Realm을 사용시 이미지를 Documents에 저장할때 이미지 URL로 저장하는 방법은?

Thor_yeom 2023. 9. 6. 01:58

 

Realm을 사용시 이미지를 Documents에 저장할때 이미지 URL로 저장하는 방법은?

결론을 미리 말하자면

고유한 ID로 설정하자!!

 

경로와 jpg로 변환하는 함수를 만들고

    // MARK: - 도큐먼트 폴더에 이미지 파일 저장하는 메서드
    func saveImageFileToDocument(fileName: String, image: UIImage) {
        
        // 1. 도큐먼트 폴더 경로 찾기
        guard let documnentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
        // 2. 경로 찾기
        let fileUrl = documnentDirectory.appendingPathComponent(fileName)
        print("fileUrl",fileUrl)
        // 3. 이미지 변환
        guard let data = image.jpegData(compressionQuality: 0.5) else { return }
        
        // 4. 이미지 저장
        do {
            try data.write(to: fileUrl)
            print("document에 생성된 사진 주소 : \(data)")
        } catch {
            print(error)
        }
    }

 

대부분 이렇게 사용합니다.

 

 

여기서 의문이 하나 들었습니다. 

고유한것만 들어가면 되는거 아니야?? 굳이 ID만 넣어야돼??

 

이러한 의문점과 호기심에서 시작한 포스팅입니다

(참 사서 고생한다 그쵸? ㅋㅋ)

 

 

그럼 시작하겠습니다.

 

Documents 파일에 이미지가 어떻게 저장되는지 부터 뜯어보겠습니다.

saveImageFileToDoucumnet(fileName: tasks._id, image: cell.bookImage.image!)메소드가 실행이되면

 

 다음과 같이 Document 파일에 id.jpg 형식으로 저장이 됩니다.

 

 

그렇다면 고유한 ID 말고 임의의 값을 만들어서 넣게되면 어떻게 될까요??

 

네 저희가 정한 이름으로 저장은 되지만

saveImageFileToDocument 메소드를 호출하게 되면 

새로운 이미지 파일이 생성되지 않고  기존 이미지에 덮어 씌어지게 됩니다.

 

여기까지는 다들 아시죠?

(영차!)

 

아 ~ 그래서 고유한 ID를 사용해서 겹치지 않게 저장하는거구나 

 

자 그럼 여기서 기출변형 들어갑니다 

 

고유한게 ID만 있는게 아닌데... 이미지의 주소값도 고유하니까 가능하지 않아?

 

그래서 해봤습니다.

selectedItem.thumbnail : 카카오톡 book url 입니다.
saveImageFileToDocument(fileName: "\(selectedItem.thumbnail).jpg", image: cell.bookImage.image!)

// 카카오톡 url 주소 : https://search1.kakaocdn.net/thumb/R120x174.q85/?fname=http%3A%2F%2Ft1.daumcdn.net%2Flbook%2Fimage%2F6092351%3Ftimestamp%3D20230905155030

 

에러 발생하고 Document 파일에 이미지는 추가되지 않았습니다.

 

 

에러를 해석해보면 

 주소 "http ~~" 가 존재하지 않아

 

엥? 이게 무슨일이죠?



분명 각 이미지마다 고유한 주소를 갖고 있는데 말이죠...

 

 

원인은!!

 

받아온 이미지 url ( 여기서는 카카오톡 book 이미지 url)에...

 

/  가 있기 때문입니다.

 

이게 무슨 일이죠?

(오늘 포스팅 쉽지 않을거 같다...그 춋?)

 

파일 디렉토리는 파일을 읽을때 / 를 기준으로 인식하게 됩니다.

 

예시로 현재 프로젝트가 어디에 위치에 있는 확인해보겠습니다.

 

/ 를 기준으로 파일로 접근하는 것을 볼 수 있습니다.

 

자 그렇다면 컴파일 오류가 났던 부분을 다시 보겠습니다.

 

 ~ Documents/ 뒤로 보면 https://  쏼라 쏼라 / 쏼 / .... 

/ 가 엄청 많이 있습니다.

 

디렉토리 : 어? /가 있네? 그럼 /를 기준으로 파일에 접근하자... 

 

 

 

그렇다면... 받아온 이미지URL를 로직을 통해
/ 를 모두 제거하면 가능하지 않나요?

 

네 가능은 합니다만 그것은 독자분들께 양보겠습니다...

(절대 하기 싫어서 아님니다... 아닐게요...)

 

 

 

 

 

 

 

 

 

 

 

 

카카오 url에서 / 만 제거하는 방법은 무엇이 있을까요?

바로  replacingOccurrences 메소드를 이용하면 됩니다. 

replacingOccurrences(of: , with: )

 

적용해보도록하죠 

이렇게 Documents / 뒤로

/가 모두 빠진 것을 볼 수 있습니다

쉽고 간단한 ID를 쓰면... 번거로운 작업 안해도 되겠죠? ㅎㅎ

 

 

결론

 

FileManager는 디렉토리를  / 를 기준으로 인식하기 때문에 

url에 /가 있으면 컴파일 에러가 발생하고 이미지가 Documents에 저장되지 않는다.

(심심하면 직접 해보세요...권장합니다 ㅎㅎ)

 

 

 

 

그렇다면 / 가 없으면 어떤것이든 되나요?
(너 참 끈질기구나...)

 

/ 만 없다면 무엇이든 이름을 정할 수 있습니다.

 

실헹을 해보면 새롭게 정의한 이름으로 만들어진것을 볼 수 있습니다.

 

물론... saveImageFileToDocument()메소드를 또 실행하면

고유하지 않기 때문에 파일이 덮어씌어 집니다.

 

 

아 ~ 카카오톡 이미지 url이 잘못된게 아니고

디렉토리 인식문제구나 

 

네 맞습니다.

 

 

 

이대로 끝내면 재미없겠죠?

왜 그렇게 인식하는지 찾아보겠습니다.

 

 

바탕화면에 /test 파일명으로 만들어보겠습니다.

 

터미널로 현재 바탕화면에 있는 것들을 찍어보면

:test 라고 보입니다.

 

파일명을 /test라고 만들었는데... 어떻게 된 일까요??

 

 

애플에서는 파일명에 / 가 들어가 있으면 디렉토리 인식을 위해 : 으로 변환합니다.

그렇다면 이런 경우에는 어떻게 터미널에 표현 될까요?

\가 있기는 하지만 / 자리는 : 으로 대체되었습니다.

 

 

애플에서 정책적으로 설정을 해놨기 때문에

애플의 정책을 따르는 Xcode에서도 역시나 적용하게 됩니다.

 

 

 

 

오늘의 한줄 평 : 고유 ID를 사용하자...

 

 

이상 먼저해보고 대신해보는 아무 개발자 였습니다.