스캐니(Scanny) – 아이폰용 스캐너앱

저는 개인적으로 개발언어를 스터디 하는 방법으로 마켓 릴리즈를 목표로 제품을 하나 만들어가며 스터디하는 것을 좋아합니다. 목적이 분명하면 생각보다 빠르게 프레임워크의 구조와 내용을 파악할 수 있습니다. 플러터(Flutter)를 스터디하기 시작하면서 벌써 세번째 앱을 앱스토어 릴리즈 했는데요. 앞의 두개는 이것을 만들면서 앱스토어에서 플러터가 어떻게 업로드 되고 돌아가는지를 확인하기 위해 짬짬이 만든것 이었습니다.

스캐니(Scanny)는 폰카메라를 이용해 문서를 촬영해서 자동으로 문서를 인식하고 사진내에서 문서만 추출해서 노이즈를 제거하는 등의 전처리를 거치고 최종적으로 OCR을 위한 깨끗한 문서를 만들어 문자인식(OCR)을 하거나 PDF로 변환하는 기능을 가진 앱입니다.

책을 단위별로 스캔하기위하여 폴더 시스템의 UI를 만들어 책단위 혹은 챕터 단위로 스캔을 할수도 있습니다. PDF 출력을 위하여 리스트에서 전체를 선택하거나 일부 그리고 드랙 & 드롭으로 순서를 바꾸어 PDF를 만들 수도 있습니다.

촬영한 문서는 OCR 문자인식 기능을 이용하여 한글/영문을 자동인식하여 텍스트로 변환하여 저장하고 공유할 수 있습니다. 향후 더 많은 언어를 지원할 계획입니다.

https://apps.apple.com/kr/app/id1529856835

앱은 무료 아닙니다. 4,900원입니다. 광고 없습니다. 현재 목표는 앞으로 10년간은 업그레이드를 하려고 생각하고 있습니다. 아래 링크에서 확인하세요.


둘째가 만들어준 아이콘

이 앱은 플러터를 이용해 개발되었기 때문에 당연히 안드로이드를 지원합니다. 플레이스토어에 런칭도 할 수 있습니다. 앞의 테스트 앱에서 테스트 해봤습니다. 하지만 앱의 기능상 카메라에서 문서 인식 기능이 매우 중요한데 안드로이드에서 약간 불안정한 상황이 발생하고 있어서 좀더 보완을 거친후에 업로드 하려고 생각중입니다.

위의 글은 스토어 런칭 광고성 글입니다. 여기서부터는 개발자 입장입니다. 플러터(Flutter)는 모바일 개발을 위한 다할나위없이 훌륭한 도구입니다. 기본적으로 아이폰과 안드로이드를 동시에 지원하는 멀티 플랫폼 개발툴이구요. 참! 최근에는 베타상태 이긴 하지만 웹과 윈도우도 지원하기 시작했습니다. 그리고 프레임워크가 수년째 접어들면서 패키지 라이브러리와 개발자 생태계도 아주 훌륭해 졌습니다.

개인적으로는 지난 수년간 React & Vue 들을 통하여 상태(State)와 그 상태의 변경이 익숙해져 있었기 때문에 여럽지 않게 적응 했을 수도 있지 않았을까 싶지만 네이티브만 개발하던 개발자라면 Provider와 State 에대한 개념이 약간(?)은 걸림돌이 되지 않을까 싶기도 합니다만 매우 좋은 도구이고 충분히 투자 할만한 가치가 있다고 생각합니다.

Change Log

2020-11-13 : V1.0 Initial Release
2020-11-19 : V1.1.0
컬러문서 스캔 기능 추가

iOS/Swift – iCloud Drive에 파일 업로드 하기

2011년 4월에 애플 앱스토어에 업로드한 Fake Location이 어뷰징 요소가 있다는 이유로 2020년 4월에 스토어에서 강제로 퇴출당했다. 이걸 마지막으로 앱스토어에 판매중인 앱이 한개도 남지 않게되어 새로운 앱을 하나 만들기로 했다.

몇일간 남는 시간을 쪼개어 그럭저럭 보이스를 녹음하고 플레이하는 작업을 하고 있었는데 알수 없는 문제에 봉착했다. 녹음된 보이스 파일은 아이폰에 저장되어야 하고 옵션으로 iCloud Drive에 저장되어야 해서 iCloud에 저장하는 기능을 추가 했는데 파일은 분명히 저장이 되고 원격 플레이까지 정상적으로 되는데 iCloud Drive에 폴더와 파일이 보이지 않는 문제가 발생했다.

알고보면 간단한 문제였지만 문제라는게 항상 그렇듯 모르면 괴로울 뿐이다. 게다가 코드 문제라기보단 설정(?) 문제라면 해결후 허무함까지 동반한다.

아이폰 로컬 폴더 얻기

아이폰 로컬 도큐먼트 폴더를 얻는 방법은 아래의 코드로 저장할 파일을 생성 할 수 있다. 생성된 audioFilename을 AVAudioRecorder에 넘겨주면 녹음이 완료된후 파일이 생성되는 것을 확인 할 수 있다. 아래 코드의 결과로 대략 이런 로케이션이 얻어진다.

file:///var/mobile/Containers/Data/Application/9F57DEC2-3A40-40AA-9EC5-5D104E94053F/Documents/voice.m4a

let saveFilename = "voice.m4a"
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let audioFilename = path!.appendingPathComponent(saveFilename) 

iCloud Drive 원격 폴더 얻기

원격 폴더를 얻는 방법은 약간의 설정작업을 해야한다. Xcode의 Signning & Capability탭에서 +Capability 탭을 선택하여 iCloud 사용설정을 해야한다. 물론 이걸 하려면 개발자 계정이 필요하다.

설정방법

위와 같은 설정을 해주면 .entitlement 파일이 생성된다. 그리고 아래 코드를 이용하면 iCloud Drive 폴더에 파일을 생성 할 수 있다. 파일명이 아래처럼 생성된다. 레코딩 결과가 생성된 파일명으로 잘 저장되었다.

file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~*****/Documents/voice.m4a

let saveFilename = "voice.m4a"
let path = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
let audioFilename = path!.appendingPathComponent(saveFilename) 

그런데 폴더가 보이지 않는다

iCloud Drive에 파일을 업로드 했으니 당연히 나의 맥북 Finder 에 iCloud Drive에 오디오 파일이 보여야 하는데 보이지 않았다. 여기에 보이지 않으면 파일을 복사하거나 이동 시킬 수 없다. 난감하네… 그래서 3일을 까먹었다. 결론적인 이야기지만 클라우드에 파일을 업로드 하고 사용자가 손대지 못하게 하려면 여기까지만 하면 된다. 물론 아이폰의 설정 – iCloud – 저장공간관리 – (앱) – 에서 삭제 할 수는 있다.

문제의 해결은 매우 간단했다. info.plist에 아래와 같은 Key값을 추가 해주면 된다. 물론 key는 각자의 것을 사용해야 한다. 개발자가 코드로 문제를 해결 못하고 설정때문에 몇일씩 까먹고 나면 매우 허무해진다. ^^; 이건 아래의 stackoverflow 링크의 중간쯤에 ‘난 이렇게 해결했어’ 가 있었는데… 글타래가 길어서 대충 읽고 넘어가느라 못본거 였던것 뿐이었다. 결국 3일째 모든 대답들을 다시 꼼꼼히 읽고 다 시도해 보고서야 문제를 찾을 수 있었다. 교훈은 좀 더 꼼꼼해 져야 한다.. 정도?

<key>NSUbiquitousContainers</key>
<dict>
    <key>iCloud.net.redacted.docTest</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>Any</string>
    </dict>
</dict>

https://stackoverflow.com/questions/25203697/exposing-an-apps-ubiquitous-container-to-icloud-drive-in-ios-8

이 설정을 추가하면 아이폰의 파일앱 그리고 계정이 연결된 맥북 또는 다른 컴퓨터에서 생성된 폴더와 파일을 확인 할 수 있다.

이 프로젝트는 현재 대략 20% 정도 진행되었다. 시작만 해놓고 마무리는 하지 못한 일들이 너무 많아서 이제는 외부에 공표를 해가며 스스로를 채찍질을 해보려고 하고는 있지만 과연 마무리를 할 수 있을지는 잘 모르겠다. 블로그 한개 썻으니 그나마 보람이 있는것일까?