Skip to content

BookKitty/BookKitty-iOS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BookKitty-iOS

책냥이 서비스 iOS 앱 레포지토리

1조-커버


Chapter 1.

책냥이 서비스를 소개합니다

1) 서비스 소개

앱스토어 이미지 앱스토어 이미지 앱스토어 이미지 앱스토어 이미지 앱스토어 이미지
Appstore Image 1 Appstore Image 2 Appstore Image 3 Appstore Image 4 Appstore Image 5

2) 서비스 목표와 주요 가치

  • 책 기반의 지식 탐색과 습득
    • 책냥이가 지향하는 것은 도서 추천이 아닌, 독서 추천입니다.
    • 사용자의 질문에 대해 AI사서 책냥이가 그 답을 얻는 데 도움이 될 수 있는 책을 소개합니다. 책이 가진 세세한 정보들을 통해 사용자가 책을 읽고, 책을 통해 답변을 얻도록 유도합니다.
    • 책을 통해 지식을 습득하는 습관, 독서 문화를 장려합니다.
  • 보유 도서 관리
    • 사용자의 보유 도서를 쉽게 관리할 수 있도록 지원하는 모바일 책장 기능을 제공합니다.
    • 사용자가 앱을 통해 확인할 수 있도록 하여 책의 중복 구매 방지를 돕습니다.
  • 책 등록의 편리성 제공
    • 사진 촬영을 통해 해당 책의 상세 데이터를 검색하여 앱에 저장합니다.
    • 단순 촬영만으로도 책 정보 입력없이 쉽게 책 정보를 얻도록 돕습니다.
    • 책장 촬영 기능 등을 통해 다수의 책을 한번에 쉽게 추가할 수 있는 편의성을 제공합니다. *wip
  • 사용자 보유 도서의 활용
    • 책냥이는 사용자가 이미 소유한 책들의 활용 가치를 새롭게 재생산합니다.
    • 사용자의 질문에 대해 현재 사용자가 소유한 책을 우선적으로 고려하여, 사용자가 서점에 갈 필요없이 쉽게 답을 얻을 수 있도록 답변합니다.
    • 사용자가 가진 책을 기반으로 사용자의 독서 취향을 분석하고 새로운 책을 추천합니다.
  • 힙한 취미로서의 독서 장려
    • 2024년 텍스트 힙 트렌드를 통해 Z세대에서 힙한 취미로 독서 문화가 소비되고 있습니다.
    • 유행하는 밈과 표현 들을 적극적으로 활용하여, 독서 추천 서비스로서 트렌드에 맞추어 사용자의 관심을 끌고 독서 문화 장려를 촉진합니다.

*wip : 아직 기능이 완전하지 않아 현재 개발중이며, 미출시된 기능입니다.

책냥이는 사용자가 궁금한 점을 책을 통해 해결할 수 있도록 유도하는**, 독서 추천 AI 사서**입니다.

최근 젊은 세대 사이에서 독서가 힙한 취미로 자리 잡고 있는 트렌드와 결합하여 더욱 자연스럽게, 더욱 Chill하게 책과 가까워질 수 있도록 지원합니다. 이를 통해 책이 지식 습득의 핵심 수단으로 다시 자리 잡을 수 있도록 돕고, 개인화된 독서 경험을 제공하고자 합니다.

튜토리얼 이미지 튜토리얼 이미지
Tutorial 1 Tutorial 2
Tutorial 3 Tutorial 4

Chapter 2.

책냥이를 추천합니다

1) 책냥이 서비스가 집중하는 문제

  • 독서 시간이 부족한 현대인들이, 책을 통해 깊이 있는 지식 습득 기회를 놓치고 있습니다.
  • 정보 습득 수단의 주된 방법이었던 책이 그 역할을 점점 상실하고 있습니다.
  • 사용자가 보유 도서를 쉽게 기억하지 못하고 중복 구매하는 문제 발생합니다. 일일이 이를 따로 기록하여 관리하기는 쉽지 않습니다.
  • 책이 많아질수록 책을 활용하기가 어려워집니다. 많은 지식을 담고있는 책들이 책장에 꽂혀 먼지만 쌓이다가 이사할 때 버려지곤 합니다.

2) 주요 타겟

  • 독서를 힙한 문화로 받아들이고 트렌디한 라이프스타일로 즐기는 젊은 세대
  • 20~40대 성인 중 지식 습득을 목적으로 독서를 원하는 사용자
  • 다수의 책을 소유하고 있으나 체계적으로 관리하지 못하거나 중복 구매 실수를 하는 사용자
  • 가지고 있는 책의 가치를 더욱 높이고 싶은 사용자
  • 특정 주제에 대한 깊이 있는 지식을 원하는 학습자 및 연구자
  • 대중의 독서 활동을 증진시키고자 하는 단체 및 기관

Chapter 3.

책냥이는 이렇게 만들어졌습니다

우리 팀은 사용자의 만족스러운 서비스 경험 제공을 목표로 기술 선택 및 개발 방향을 정하였습니다. 아직 배움의 길에 있는 팀이지만 책냥이는 그냥 이번에 이런 거 한번 적용해보면 어떨까요? 에서 시작하지 않았습니다.

서비스를 만드는데 당면한 문제를 어떻게 기술적으로 해결할 수 있을까에 대해 고민하였고, 충분히 검증 후 해당 기술들을 사용하였습니다.

우리 팀은 프로젝트의 모든 기능을 하나의 코드베이스에 담는 대신, 핵심 기능들을 모듈화하여 라이브러리로 개발하는 방식을 선택했습니다. 이러한 접근 방식은 코드의 재사용성을 극대화하고, 유지보수를 용이하게 하며, 기능을 독립적으로 개선할 수 있도록 하기 위함입니다. 독립적인 라이브러리 구조를 채택함으로써, 향후 확장성과 성능 최적화가 필요한 경우에도 개별 모듈을 손쉽게 개선할 수 있습니다.


1) 기술 스택

범위 기술 이름
AI 기술 OpenAI ChatGPT, DeepSeek
의존성 관리 도구 SPM
형상 관리 도구 GitHub, Git
아키텍처 MVVM, Coordinator
인터페이스 UIKit
비동기 처리 RxSwift, Async/Await
레이아웃 구성 SnapKit
내부 저장소 CoreData
이미지 처리 Kingfisher → 자체 이미지 캐싱 라이브러리
네트워킹 URLSession
코드 컨벤션 SwiftLint, SwiftFormat
커밋 컨벤션 Udacity Git Commit Message Style Guide
OCR 처리 Vision Framework, CoreML

2) 프로젝트 설계

앱 아키텍처 설계 단계에서 역할분리가 명확해 협업이 용이한 아키텍처인 계층형 아키텍처를 채택하였습니다.

Untitled 002

계층분리 기준

  • 먼저, 네트워크 및 영구 저장소와 같은 세부 사항을 Infra 계층으로 분리하였습니다. 또한, 도메인이 직접적으로 이러한 세부 사항을 알지 않도록, 중간 계층인 Data 계층을 두어 추상화하였습니다.
  • 비즈니스 로직을 Service 계층으로 분리하는 방안도 고려했으나, 주요 로직을 모듈화하여 정리했기 때문에 별도의 Service 계층을 두지 않았습니다.
  • 마지막으로, UI 로직과 상태 관리를 담당하는 Presentation 계층을 분리하여 역할을 명확히 했습니다.

코디네이터 패턴 적용

  • 프로젝트의 아키텍처 설계 단계에서 MVVM-C 패턴을 도입하여 ViewController의 역할을 단순화하고, 화면 전환 로직을 분리하는 방식을 채택했습니다.
  • 기존 MVVM 패턴만으로는 화면 전환 책임이 View(ViewController)에 남아 있어 코드 복잡도가 증가하고, 모듈 간 결합도가 높아지는 문제가 발생할 가능성이 있었습니다. 이를 해결하기 위해 Coordinator 패턴을 함께 적용하여 화면 전환 흐름을 별도의 컴포넌트에서 관리하도록 설계했습니다.
  • VC에서 화면전환 로직 분리로 UI에 대한 SRP를 준수할 수 있게 되었습니다. VC의 책임이 가벼워짐에 따라 코드가 간결해졌으며, 화면전환 기능을 쉽게 관리하고 유지보수 할 수 있게 되었습니다.

DIP 적용

  • 계층형 아키텍처의 주요 문제점은 상위 계층이 하위 계층에 강하게 의존한다는 점입니다. 이로 인해, 하위 계층이 변경될 경우 상위 계층에도 영향을 미칠 위험이 있습니다.
  • 이를 해결하기 위해, 상위 계층이 하위 계층의 구현체가 아닌 인터페이스(프로토콜)에 의존하도록 DIP(Dependency Inversion Principle)를 적용하였습니다.
  • 그 결과, 세부 구현이 변경되어도 상위 계층에 영향을 주지 않으며, 객체 간의 결합도가 낮아져 독립성이 강화되었습니다. 이를 통해 테스트가 더욱 용이해지는 효과도 얻을 수 있었습니다

기술 적용 이유

  • 다섯 명의 개발자가 협업하는 과정에서 역할을 명확히 분리하고 유지보수성을 높일 수 있는 아키텍처를 고민했습니다.
  • 처음에는 변경에 강한 클린 아키텍처를 고려했으나, 팀원 간의 이해도 차이와 높은 러닝커브가 문제로 작용할 수 있다고 판단했습니다. 이에 따라, 각 계층이 명확한 역할을 가지면서도 학습 부담이 적은 계층형 아키텍처를 선택하였습니다.
  • 계층형 아키텍처의 단점인 상위 계층이 하위 계층에 의존하여 변경에 취약한 문제점을 인식하고, 이를 해결하기 위해 상위 계층이 구현체가 아닌 인터페이스(프로토콜)에 의존하도록 DIP를 적용하였습니다

기술 적용 결과

  • 역할 분리가 명확해 각자가 맡은 부분을 독립적으로 개발할 수 있었고, 코드 충돌이 거의 발생하지 않았습니다.
  • 각 계층이 인터페이스(프로토콜)에 의존하기 때문에, 세부 구현이 변경되어도 상위 계층이 영향을 받지 않았습니다.
  • Mock 객체를 활용한 독립적인 개발 및 테스트가 가능해져, 병렬적인 개발이 원활하게 이루어졌습니다.
  • 이로 인해 개발 병목현상 없이 지속적으로 개발을 이어나갈 수 있었습니다.

3) 직접 개발한 디자인 시스템 라이브러리

서비스 전반에 일관된 사용자 경험을 제공하기 위해, 우리는 디자인 시스템 라이브러리를 직접 제작하였습니다.

이 라이브러리는 앱의 UI/UX를 체계적으로 관리할 수 있도록 설계되었으며, 공통된 스타일과 컴포넌트를 정의하여 서비스 전반에 걸쳐 일관된 비주얼과 사용성을 유지할 수 있도록 도와줍니다.

이미지 1 이미지 2 이미지 3
CleanShot 1 CleanShot 2 CleanShot 3

기술 적용 이유

  • 이를 통해 팀 멤버들의 반복적인 UI 구현 작업을 최소화하고, 보다 빠르게 화면을 구성할 수 있도록 하였습니다. 각 뷰에서 마치 레고를 조립하듯, 각 컴포넌트들을 import 하여 초기화만 하면 됩니다. 새로운 기능들을 구현하는 데 있어서도 개발 시간을 단축시킬 수 있었습니다.
  • 또한, 디자인 변경이 필요한 경우, 개별 화면을 수정하는 것이 아니라 라이브러리 내의 요소만 업데이트하면 되므로 유지보수가 훨씬 용이해졌습니다. 이 후 디자인의 대대적 변경이 필요할 경우, 새로운 디자인 시스템 import 만으로 바로 변경할 수 있습니다.

수많은 회사들이 디자인 시스템을 만들어 운영하고 있습니다. 미리 디자인 시스템을 직접 함께 만들어 운영해봄으로써 디자인 시스템 그 자체와 왜 이런 시스템을 운영하는 지에 대해 이해와 경험을 해둔다면 좋은 경쟁력이 될 수 있을 것이라 생각하였습니다. 이미 시스템을 운영하는 회사에서는 빠르게 적응 및 활용을 할 수 있으며, 아직 시스템을 구축하지 못한 곳에서는 이러한 역할을 감당할 수 있는 능력을 갖추고자 하였습니다.

기술 적용 결과

  • 실제 개발 시 디자인과 관련된 영역에 개발자의 부담이 줄어들고, 레고 조립하듯 컴포넌트를 쌓아갈 수 있어 개발 속도가 빨라졌습니다.
  • 통일성 있는 디자인을 유지하는 데 많은 도움이 되었습니다. 디자인 컨벤션을 따로 준수해야 하는 노력이 크게 감소하였습니다.
  • 디자인 변경이 일괄적으로 편하고 쉽게 이루어져서, 유지보수 관리에 효율성이 높아졌습니다.
  • 왜 각 회사들이 자체 디자인 시스템을 만들어 운영하는 지에 대해 아주 살짝이나마 맛을 볼 수 있었던 경험이었습니다.

4) BookMatchKit – OCR 및 생성형 AI 검증 라이브러리

책냥이 서비스의 핵심 기능 중 하나는 사용자의 질문을 분석하고, 적절한 책을 추천하는 AI 기반의 검색 기능입니다. 이를 위해, 우리는 BookOCRKit, BookRecommendationKit을 포괄하는 BookMatchKit이라는 자체 라이브러리를 개발하였습니다.

BookMatchKitOCR(광학 문자 인식) 기능과 생성형 AI 모델을 효율적으로 관리 및 고도화하는 역할을 합니다. OCR 기능을 통해 사용자는 책장을 촬영하거나 책의 정보를 쉽게 등록할 수 있습니다. AI는 질문을 분석하여 해당 책에 대한 검증 절차를 시행합니다.

우리 팀은 핵심 기술을 라이브러리 형태로 분리함으로써, 향후 다양한 서비스에 쉽게 적용할 수 있도록 설계하였습니다. 또한, 지속적인 AI 모델 개선과 OCR 성능 최적화를 진행할 때, 개별적으로 테스트하고 배포할 수 있는 유연성을 갖추고 있습니다.

  • 상세보기

    라이브러리 구현 배경

    • OCR
      • 사용자가 일일이 책을 입력하여 검색 후 책장에 등록하는 프로세스는 굉장히 번거로운 일입니다. 설문조사를 통해 사용자가 이러한 과정 속에서 서비스 이탈율이 높게 나타날 수 있다는 것을 예측할 수 있었습니다.
      • ISBN 이나 정확한 책 정보의 입력 과정은 책을 많이 입력해야 하는 사용자 입장에서 굉장히 큰 부담스러운 작업이며, 책장 기능 자체를 활용하지 않게 될 가능성이 높습니다.
      • 이에 따라 사용자가 책을 직접 촬영하여 제목을 추출하고, 이 데이터를 이용해 책 데이터를 검색하여 저장하는 방식을 구현할 필요가 있었습니다.
    • 생성형 AI 모델
      • 사용자가 이미 소유한 책들을 활용할 수 있는 방안을 제안하는 기능이 필요하였습니다. 또한 사용자로 하여금 책을 읽는 행위, 독서를 하도록 유도하기 위한 방안을 고민하여 보았습니다.
      • 가지고 있는 책 데이터를 기반으로 직접 로직을 설계하는 방안도 고려하였으나, 정말 다양한 사용자의 니즈를 충족시킬 수 있는 기능을 제공하기 위해 생성형 AI를 활용하는 것으로 결정하였습니다.
      • 생성형 AI를 통해 사용자의 질문에 대해 답을 얻을 수 있는 책을 선정하고, 해당 책을 선정한 이유를 텍스트로 작성하도록 하였습니다. 이를 통해 사용자가 책냥이가 스스로 인격체를 가지고 서로 커뮤니케이션을 나누는 것과 같은 경험을 주고자 하였습니다.
    • 이를 통해 아래와 같은 서비스 흐름을 가지게 되었습니다. 이러한 패턴은 냉장고 관리, 의류 관리 등 여러 분야에서 많은 소비자들의 니즈에 부합하여 많은 조직들을 통해 서비스되고 있습니다. 하지만 도서 쪽은 아직 이러한 기능을 모두 포괄하는 서비스가 없는 영역이었습니다.

    CleanShot 2025-02-24 at 10 20 59@2x

    라이브러리 구현 과정

    • OCR
      • 기존의 도서 검색 방식은 ISBN 또는 정확한 제목 입력 요구, 사용자가 책을 직접 촬영하려면 표지에서 제목 자동 추출이 필요. 첵 제목을 식별하고 OCR을 거쳐 추출해야 했습니다.
      • 책 표지에서 텍스트를 추출하기 위해서는 OCR을 사용하여 인쇄된 제목을 감지하고 이를 기반으로 검색. 하지만 OCR만으로는 표지 디자인 요소와 텍스트 구분이 어려웠습니다.
      • CoreML 기반의 객체 탐지 모델 사용해서 첵 제목 영역을 먼저 추출한 후, OCR을 적용하였습니다.
      • 또한 CoreML 활용한 제목 위치 탐색 + 전처리 과정을 추가하여 조명과 각도에 영향을 덜 받도록 개선하였고, 텍스트 정제 및 패턴 필터링을 적용하여 정확도를 높였습니다.
      • 결과
        • OCR 정확도 향상, 한글 OCR 기능 개선
        • OCR을 전체 이미지에 실행하는 대신, CoreML이 감지한 영역만 실행하여 최적화
        • 이미지 전처리 -> 대비 조정, 노이즈 제거를 통해 저화질에도 텍스트 감지, 환경 영향 감소
        • 사용자 편의성 증가
      • 한계
        • 처리 속도 지연 (CoreML 모델 실행, OCR, 이미 전처리 과정이 연속적으로 실행됨)
        • NLP 후처리 한계 (OCR 결과를 보정하는 과정에서 유효한 단어까지 삭제 될 가능성 존재
        • CoreML모델의 한계 -> 책 제목이 있는 위치를 완벽하게 예측 하지 못함 (다른 요소를 인식 하는 경우가 있음 -> 저자명, 홍보 문구 등)

BookOCRKit - CoreML, Vision 프레임워크를 활용한 촬영을 통한 책 매칭 시스템

  • OCR 전처리 및 CoreML 기반 텍스트 탐지 시스템 상세보기


    1. OCR 전처리

    1. 목적

    OCR 성능을 극대화하기 위해 촬영된 이미지를 분석하고 최적화하여 Vision OCR이 텍스트를 정확하게 추출할 수 있도록 지원합니다.

    1. 전처리 과정 단계별 설명
    단계 설명
    대비 향상 (CLAHE 적용) 명암 대비를 조정하여 텍스트가 명확하게 구분되도록 처리
    적응형 이진화 (Adaptive Threshold 적용) 배경과 텍스트를 구분하여 OCR이 쉽게 분석할 수 있도록 변환
    노이즈 제거 (Median & Morphology 필터 적용) OCR이 인식할 필요 없는 작은 점, 노이즈 등을 제거
    선명도 향상 (Sharpening 적용) 흐릿한 텍스트를 선명하게 보정하여 인식률 향상
    기울기 보정 (Skew Correction) 촬영 각도에 따른 텍스트 기울기를 보정

    2. CoreML 기반 텍스트 탐지

    1. 목적

      CoreML을 사용하여 도서 표지에서 텍스트가 포함된 영역을 탐색하고, OCR의 정확도를 높이기 위해 신뢰도 기반 필터링을 수행합니다.

    2. CoreML 모델을 활용한 객체 탐지과정

      1. CoreML 모델 로드
        • MyObjectDetector5_1 모델을 불러와 도서 표지에서 텍스트가 포함된 영역을 탐지합니다.
      2. Vision 프레임워크와 연동
        • VNCoreMLModel을 사용하여 Vision 프레임워크에서 실행 가능하도록 변환합니다.
      3. 객체 탐지 요청 실행
        • VNImageRequestHandler를 통해 이미지 분석을 진행합니다.
        • VNCoreMLRequest를 사용하여 CoreML 모델이 예측한 객체를 반환합니다.
      4. 신뢰도 기반 필터링
        • OCR 실행 전, 신뢰도(confidence)가 0.3 미만인 객체는 제거됩니다.
      5. 탐지 실패 시 예외 처리
        • CoreML이 텍스트를 탐지하지 못한 경우, 전체 이미지 OCR을 수행하도록 Fallback 처리됩니다.

    3. OCR 실행 (Vision 프레임워크 활용)

    1. 목적

      CoreML이 탐지한 텍스트 영역에서 OCR을 실행하여 최적의 텍스트를 추출합니다.

    2. OCR 과정

      1. 그레이스케일 변환
        • OCR 실행 전, 그레이스케일 변환을 수행하여 가독성을 높였습니다.
      2. OCR 요청 실행
        • VNRecognizeTextRequest를 사용하여 텍스트를 인식합니다.
        • recognitionLanguages = ["ko", "en"] 설정으로 한글과 영어만 OCR 적용하도록 진행하였습니다. 주 사용자 층을 고려하여, 기타 글자로 인한 인식 정확도 하락을 방지하기 위함입니다.
      3. OCR 결과 필터링
        • 신뢰도가 높은 텍스트만 topCandidates(1).first?.string을 통해 추출합니다.
      4. 예외 처리
        • OCR 실패 시 BookMatchError.OCRError를 반환하도록 처리하였습니다.

    4. 결론

    • CoreML을 활용하여 OCR 대상 영역을 선별적으로 탐지하고, Vision 프레임워크를 이용해 최적의 OCR 결과를 도출하는 구조를 적용하였습니다.
    • 이를 통해 OCR 인식률이 향상되었으며, 불필요한 텍스트를 제거하여 검색 성능을 개선할 수 있었습니다.
    • 이미지 전처리 과정을 최적화하여 다양한 촬영 환경에서도 안정적인 인식 성능을 유지하도록 설계되었다.
  • 도서 촬영 OCR 후처리 로직 상세보기


    도서 표지 OCR 결과로부터 정확한 도서를 매칭하기 위해 Vision 프레임워크와 네이버 책 검색 API를 결합한 후처리 시스템을 설계 및 구현했습니다. 특히 라벨링되지 않은 OCR 결과에 대한 처리와 이미지 유사도 기반 검증을 도입했습니다.

    기술 선정 이유

    • 텍스트 라벨링 기반 초기 시스템의 한계
      • OCR 결과에서 제목/저자를 명확히 구분할 수 없는 문제가 있었습니다.
      • 또한, 텍스트가 의미적 구분 없이 단어 배열로만 전달되는 한계가 있었습니다.

    해결 방안

    • 순차적 검색 방식 채택: 크기순으로 정렬된 텍스트를 점진적으로 조합하여 검색을 수행했습니다.
    • 이미지 유사도 시스템 도입: Vision 프레임워크의 특징점 추출 기능을 활용한 검증을 구현했습니다.

    핵심 기술 구현

    1. 순차적 도서 검색 시스템

    • 크기순으로 정렬된 텍스트를 점진적으로 조합하여 검색을 수행합니다.
    • 검색 결과가 3개 이하가 되면 이전 결과를 최적 매칭으로 판단합니다.

    2. 이미지 유사도 기반 검증 시스템

    • Vision 프레임워크를 활용해 이미지 간 유사도를 0~1 사이 값으로 계산합니다.
    • 전처리, 특징점 추출, 거리 계산의 3단계로 구성되어 있습니다.

    기술 적용 결과

    • 매칭 정확도 향상: 텍스트와 이미지 기반의 하이브리드 검증으로 매칭 정확도가 크게 개선되었습니다.
    • 안정성 확보: OCR 결과의 불안정성을 순차적 검색과 이미지 유사도로 보완했습니다.

5) BookRecommendationKit - ChatGPT와 네이버 책 검색 API 활용 독서 추천 라이브러리

사용자의 요구사항에 최적화된 도서를 추천하기 위해 ChatGPT API와 네이버 책 검색 API를 결합한 도서 추천 시스템을 설계 및 구현했습니다. 특히 LLM의 환각(hallucination) 현상으로 인한 비정상 데이터 추천 문제를 해결하기 위해, 데이터 기반의 검증 시스템과 재시도 메커니즘을 도입했습니다.

  • 상세보기

    기술 선정 이유

    GPT api만을 사용하고자 했던 초기 시스템 기획의 한계

    • Hallucination으로 인해 존재하지 않는 도서 정보를 반환하는 문제가 있었습니다.
    • 또한, 책 촬영을 통한 도서 추가 로직의 경우, 멀티모달 LLM을 사용함에 따라 비용 문제가 있었습니다.

    해결 방안

    • 하이브리드 접근 방식 채택: GPT의 맥락 이해 능력과 네이버 API의 실제 도서 데이터를 결합하게 되었습니다.
    • 데이터 기반 임계값 시스템 도입: 텍스트 유사도 측정을 통해 존재하는 책에 대한 기준을 수치화하고자 했습니다.
    • 재시도 메커니즘 구현: API 오류 및 부정확한 데이터에 대한 복원력을 최대 3회의 재시도 매커니즘을 통해 확보하고자 했습니다.

    핵심 기술 구현

    1. 데이터 기반 임계값 시스템

    // 유사도 기반 정상 매칭 판단 로직
    let isMatching = result.value[0] >= 0.42 && result.value[1] >= 0.80  // 제목, 저자 임계값
    • 37개의 테스트 케이스를 통한 반복적 실험을 통해, 제목 유사도: 0.42, 저자 유사도: 0.80으로 설정 시 가장 높은 92.8%의 매칭 정확도를 달성한다는 것을 파악할 수 있었습니다.
    • 초기 기획과는 달리 출판사 정보는 변별력이 낮다는 분석 결과에 따라 제외하게 되었습니다.

    2. 재시도 메커니즘

        var retryCount = 0
        var currentBook = book
        var previousBooks: [RawBook] = newBooks
        var candidates = [(BookItem, Double)]()
    
        func tryMatch() -> Single<BookItem?> {
            guard retryCount < maxRetries else {
    	        ...
            }
    
            *return validateRecommendedBook(currentBook)
                .flatMap { result -> Single<*BookItem?> in
                    if let matchedBook = result.book {
                        if result.isMatching {
                            return .just(matchedBook)
                        } else {
                            return openAiAPI.getAdditionalBook(
                                question: question,
                                previousBooks: previousBooks + [currentBook]
                            )
                            .flatMap { newBook -> Single<BookItem?> in
                                    currentBook = newBook
                                    return tryMatch()
                                }
                            }
                        }
                    } else {
                        return .just(nil)
                    }
                }
        }
    
        return tryMatch()
    }
    • 재귀적 호출을 통해 최대 3회까지 재시도하여 존재하는 도서 매칭 확률을 극대화하고자 했습니다.
    • 각 재시도마다 이전 추천 도서 제외하여 GPT로부터 중복된 책을 반환받지 않고자 했으며, 3회 실패 시에도 가장 높은 유사도의 도서를 반환하게 설계해 서비스의 안정성을 구축하였습니다.

    3. 자동화된 정확도 측정 시스템

    func accurancyTester(question: String, title: String) async -> Int {
        let prompt = """
        당신은 전문 북큐레이터입니다. 도서의 제목과 상세정보를 보고,
        질문에 적합한 도서인지 여부를 0이나 1로 표현해주세요.
        """
        // GPT API를 통한 자동 평가 로직
    }
    • GPT API를 활용한 자동화된 정확도 측정 시스템을 구축하였습니다.

    4. 엣지케이스 대응을 위한 고도화된 검색 전략

    1. 괄호 제외 레벤슈타인 알고리즘
    struct LavenshteinStrategyWithNoParenthesis: CalculationStrategy {
        func calculateSimilarity(_ source: String, _ target: String) -> Double {
            // 괄호 내용을 유사도 측정 대상에서 제외
            let sourceWithoutParenthesis = source.replacingOccurrences(
                of: "\\(.*\\)", 
                with: "", 
                options: .regularExpression
            )
            // 레벤슈타인 거리 계산 및 정규화
            return calculateNormalizedDistance(sourceWithoutParenthesis, target)
        }
    }
    • 도서명의 괄호 내 부가 정보로 인해 유사도가 낮게 측정되는 이슈를 해결하고자 했습니다.
    • "파이썬 for Beginner" 케이스에서 괄호 내용으로 인한 낮은 유사도 문제를 해결했습니다.
    private func searchOverallBooks(from sourceBook: RawBook) -> Single<[BookItem]> {
        Observable<Void>.just(())
            .delay(.milliseconds(500), scheduler: MainScheduler.instance)
            .flatMap { _ -> Observable<[BookItem]> in
                // 제목과 저자 검색 동시 수행
                let titleSearch = self.apiClient.searchBooks(
                    query: sourceBook.title, 
                    limit: 10
                ).asObservable()
                let authorSearch = self.apiClient.searchBooks(
                    query: sourceBook.author, 
                    limit: 10
                ).asObservable()
    
                return Observable.zip(titleSearch, authorSearch)
                    .map { titleResults, authorResults in
                        // 검색 결과 통합
                        var searchedResults = [BookItem]()
                        searchedResults.append(contentsOf: titleResults)
                        searchedResults.append(contentsOf: authorResults)
                        return searchedResults
                    }
            }
    }

    2. 저자 기반 병렬 검색

    • GPT가 추천한 책은 해당 저자의 대표작일 가능성이 높다는 점을 활용하여, 제목 검색과 함께 저자 검색도 수행해 검색 범위를 확장하고자 했습니다.
    let subTitleDivider = [":", "|", "-"]
    // 검색 결과가 없고 부제목 구분자가 있는 경우
    if searchedResults.isEmpty,
       !subTitleDivider.filter({ sourceBook.title.contains($0) }).isEmpty,
       let divider = subTitleDivider.first(where: { sourceBook.title.contains($0) }),
       let title = sourceBook.title.split(separator: divider).first {
        return self.apiClient.searchBooks(query: String(title), limit: 10)
            .asObservable()
    }
    return Observable.just(searchedResults)

    3. 부제목 분리 검색

    • 검색결과가 없을 경우, 주제목만으로 재검색을 시도해 추가 비교대상을 확보하고자 했습니다.

    기술 적용 결과

    • 정확도 향상: 초기 58.3%에서 92.8%로 **34.5%**p 향상
    • 복원력 확보: API 오류 및 부정확한 데이터에 대한 안정적인 대응 가능

6) 네트워크 모듈

API 통신 기능을 NetworkKit 패키지로 분리하여, 확장성, 안정성, 테스트 가능성을 고려해 설계 및 구현하였습니다.

  • 상세보기

    기술 적용 이유

    • 어떤 엔드포인트를 넘겨줘도 통신이 가능하고, 어떤 응답 타입이던 반환 가능한 제네릭한 HTTP 요청 기능이 필요했습니다.
    • 실제 네트워크 통신 없이도 네트워크 기능을 테스트할 수 있어야 했습니다.
    • Endpoint 프로토콜을 활용하여, base URL, path, parameter 등 엔드포인트의 필수 요구사항을 정의하였습니다.
    • Requestable 프로토콜을 통해 엔드포인트 정보를 조합하여 URLRequest를 생성할 수 있도록 하였습니다.
    • Responsable 프로토콜을 정의하여, associatedType을 활용한 제네릭한 응답 타입을 설계하였습니다.
    • Session Configuration을 주입받는 형태로 설계하여, MockURLProtocol을 활용한 테스트 코드 작성이 가능하도록 하였습니다.
    • 필요시 Alamofire 등의 서드파티 라이브러리를 대체할 수 있도록, 의존성을 최소화하고 독립적인 패키지(NetworkKit)로 분리하였습니다.

    기술 적용 결과

    • 어떤 엔드포인트든 적용 가능하며, 요청 및 응답이 유연한 네트워크 모듈을 완성하였습니다.
    • GPT API, 네이버 책 API 등 여러 API에 적용하여 실용성을 검증하였습니다.

7) NeoImage - 이미지 캐시 모듈

Swift 6에서의 동시성 안전성을 고려한 이미지 캐싱 및 로딩 라이브러리를 설계 및 구현하였습니다.

  • 상세보기

    기술 적용 이유

    • 기존 라이브러리(Kingfisher)의 동시성 모델을 Swift Concurrency로 마이그레이션하여 actor 기반 동시성 안전성을 확보하고자 하였습니다.
    • 이미지 처리 및 변환 작업을 비동기적으로 처리해 UI 스레드 차단에 대한 필요성이 느껴졌습니다.
    • 새로운 Swift 6 동시성 모델을 활용해 코드 가독성과 유지보수성을 향상시키고자 했습니다.

    기술 적용 결과

    • Swift 6의 엄격한 동시성 안전성 검사에 부합하는 안정적인 이미지 로딩 시스템을 구축했습니다.

8) LogKit - 로깅 시스템 모듈

QA 과정에서 발생하는 크래시 및 이상 동작을 재현하기 위해, 시스템 로그 정보를 파일로 저장 및 관리하는 LogKit 패키지를 설계 및 구현하였습니다.

  • 상세보기

    기술 적용 이유

    • 로그를 파일로 저장할 시 용량 관리와 같은 자원 관리 기능이 필요했습니다.
    • 로그 레벨(debug, info, warning, error, fatal)에 따라 적절한 처리가 가능해야 했습니다.
    • 위치 정보(파일명, 함수명, 라인번호)를 자동으로 캡처해 디버깅 효율성을 높이고자 했습니다.

    기술 적용 결과

    • 싱글톤 패턴을 활용해 애플리케이션 전역에서 일관된 로깅 접근점을 제공하였습니다.
    • 로그 파일 크기 자동 관리 기능을 통해 디스크 공간 효율성을 확보하였습니다.
    • 비개발자의 QA에서도 로그 파일을 통해 상세한 로그를 전달받을 수 있게 되었습니다.

9) 블로그 링크 모음

BookMatchKit 라이브러리 제작 일지

Coordinator 설계 및 구현 일지


Chapter 4.

우리 팀은 이렇게 일했어요.

명확한 일정관리

서비스 구현 타임라인 (1)

서비스 구현을 목표로, 일정과 업무를 협의하여 다음과 같이 타임라인을 설정하여 기한을 맞추고자 노력하였습니다. 한달이라는 길지도 짧지도 않은 시간 속에서 각자 최선을 다해 업무에 집중하였습니다.

태스크 매니저 운영

이미지 1 이미지 2
CleanShot 1 CleanShot 2

또한 저희 팀은 Task Manager를 적극적으로 활용하여 협업을 진행하였습니다. Jira 서비스를 참고하여, 마일스톤과 같은 큰 목표를 Epic으로 설정하고 하위 Task들을 생성하여 서로의 업무를 체크할 수 있도록 하였고, 하루 단위로 업무를 쪼개어 소소하지만 확실한 성취를 이루어가며 작업하였습니다.

멤버별 역할

  • 권승용: 프로젝트 설계

    • 프로젝트 (계층형 아키텍처) 설계
    • NetworkKit 구현
    • Logger 시스템 구축
  • 김형석: 핵심 라이브러리 구현

    • BookOCRKit(도서 인식 및 매칭 서비스) 설계 및 구현
    • BookRecommendationKit(도서 추천 서비스) 설계 및 구현
    • NeoImage(이미지 캐싱 라이브러리) 설계 및 구현
  • 전성규: 프로젝트 설계

    • 프로젝트 (MVVM-C) 설계
    • Firebase GA, Crashlytics 로깅 시스템 구축
  • 반성준: CoreML 및 OCR 담당

    • CoreML을 활용한 도서 제목 탐지 모델 적용 및 OCR 영역 최적화
    • OCR 전처리 로직 개선
  • 임성수: 디자인 관리자

    • 앱 디자인 및 기획
    • 디자인 시스템 구축
    • 코어데이터 구축

Chapter 5.

책냥이 미래 계획

책냥이 서비스는 단순한 도서 관리 및 추천을 넘어, 사용자의 독서 경험을 데이터 기반으로 확장하고, 보다 체계적인 지식 관리와 탐색이 가능한 서비스로 진화하고자 합니다. 이를 위해 MVP 출시 이후 smore 플랫폼을 통해(smore → zap → notion 자동화) 피드백을 받았고, 이를 기반으로 추가 기능을 개발하고 있습니다.

CleanShot 2025-02-25 at 08 53 51@2x

책냥이에게 피드백 주기

1. 나만의 위키(Wiki) 기능 – 책 속 지식 데이터베이스 구축

단순히 책을 보유하고 있는 것에서 그치는 것이 아니라, 사용자가 읽은 책 속 지식을 데이터베이스화하여 개인 맞춤형 위키(Wiki)처럼 활용할 수 있도록 하는 것이 목표입니다. 서비스의 주요 목적 중 하나였던, 사용자의 책 활용 가치를 재생산하기 위한 추가 기능입니다.

  • 상세보기
    • 책을 통해 얻은 지식들을 정리하고, 필요할 때 검색하여 다시 찾아볼 수 있는 개인 맞춤형 지식 저장소 제공
    • 사용자가 책에서 중요하다고 생각하는 구절을 직접 입력하거나 OCR을 통해 텍스트를 추출하여 저장하고, 키워드 태깅 시스템을 도입하여 사용자가 책 속 개념을 주제별로 정리하고 연결 가능하도록 합니다.
    • 이렇게 정리된 데이터들을 기반으로 AI 요약 기능을 활용해, 책의 주요 내용을 자동 정리하여 사용자가 쉽게 리뷰 가능하며, 사용자의 관심사 및 읽은 책들의 내용을 기반으로 새로운 정보 및 관련 도서 추천을 할 수 있습니다.
    • 추후 해당 책에 대해 사용자가 자신의 지식을 공유할 수 있는 기능 추가할 예정입니다.
    • 예시:
      • ‘인공지능’과 관련된 책들을 읽고 해당 내용을 Wiki에 저장 → 사용자가 필요할 때 인공지능 관련 지식 검색 가능
      • ‘철학’ 관련 책을 다수 보유한 사용자가 새로운 철학 서적을 찾고자 할 때, AI가 Wiki에 저장된 데이터를 기반으로 맞춤 추천

2. 고도화된 촬영 인식 기능 : 빠르고 정확한 책 추가 Doing

현재 책 인식 기능을 한층 더 강화하여, 사용자가 책을 한 권씩 추가하는 번거로움 없이 여러 권을 한 번에 등록할 수 있도록 개선하고 있습니다.

  • 상세보기
    • OCR 인식률 향상: 딥러닝 기반 OCR 모델을 최적화하여 더 정확하게 책 제목 및 정보를 추출
    • 멀티북 스캔 기능: 한 장의 사진을 촬영하면 다수의 책을 자동으로 인식하여 개별 등록 가능
    • 책등(책의 옆면) 촬영 지원: 책이 쌓여있는 상태에서도 AI가 제목과 저자를 판별할 수 있도록 학습
    • 바코드 & ISBN 자동 인식: 사용자가 책의 바코드를 스캔하면 자동으로 도서 정보를 불러올 수 있도록 기능 개선
    • 예시:
      • 책장 사진 한 장을 촬영하면, 여러 권의 책을 AI가 자동으로 인식하여 앱에 한 번에 등록
      • 책을 옆으로 쌓아둔 상태에서 책등을 촬영해도 개별적으로 분류하여 자동 저장

3. 사용자 보유 도서 기반 맞춤형 추천 시스템

사용자의 독서 취향과 소장 도서를 분석하여, 단순한 인기 도서 추천이 아닌 진짜 필요한 책을 추천하는 AI 시스템을 도입할 예정입니다.

  • 상세보기
    • 보유한 책들과 연관성이 높은 도서를 추천하여 깊이 있는 독서를 유도
    • 특정 주제(예: ‘경제학’, ‘철학’, ‘SF 소설’)에 대한 사용자의 독서 히스토리를 AI가 분석하여 관련 도서 큐레이션
    • ‘지금까지 읽은 책과 어울리는 책’과 ‘새로운 관점을 제공하는 책’ 두 가지 방식의 추천 제공
    • 기존의 도서 평점 및 사용자 피드백을 활용하여 더 정교한 개인화 추천 가능
    • 예시:
      • 사용자가 ‘디지털 마케팅’ 관련 책을 여러 권 가지고 있다면, 최신 트렌드 서적이나 심화 학습용 추천 도서 제공
      • 사용자가 소설을 많이 읽는 경우, 같은 작가의 또 다른 작품 혹은 유사한 문체의 소설 추천

4. 실시간 독서 기록 및 리뷰 기능

독서 경험을 단순한 소비가 아닌 기록하고 공유할 수 있는 과정으로 확장하는 기능을 강화할 예정입니다.

  • 상세보기
    • 사용자가 현재 읽고 있는 책을 실시간으로 업데이트하고, 진행 상태를 관리 가능
    • 독서 진행률 시각화: 사용자가 책을 얼마나 읽었는지, 남은 페이지 수를 추적하여 그래프로 제공
    • 독서 리뷰 및 메모 기능: 책을 읽으면서 중요한 내용을 메모하고, 읽은 후 감상을 남길 수 있도록 지원
    • SNS 및 커뮤니티 공유 기능: 자신이 읽고 있는 책을 친구들과 공유하거나, 책에 대한 의견을 나눌 수 있도록 확장
    • 독서 습관 추적 기능: 주간 및 월간 독서량을 자동 분석하여, 사용자에게 맞춤형 독서 목표 설정 지원
    • 예시:
      • 사용자가 ‘정의란 무엇인가’를 읽고 있을 때, 앱이 읽은 페이지 수를 기록하고 자동으로 진행률을 업데이트
      • 사용자가 한 챕터를 읽고 중요한 내용을 정리하면, 자동으로 Wiki에 저장하여 이후 검색 가능
      • 친구들과 독서 목표를 공유하고, 특정 책에 대한 리뷰를 남길 수 있도록 제공

5. 책장 관리 기능의 고도화 Doing

책장 관리에 정렬, 필터링, 검색, 카테고리, 즐겨찾기 등의 기능을 추가하여, 사용자가 더 쉽고 편하게 책장을 관리할 수 있도록 할 예정입니다.

  • 상세보기
    • 정렬 기능을 통해 사용자가 책 제목, 저자명 등 원하는 순서에 따라 책장의 책 목록을 볼 수 있도록 합니다.뿐만 아니라 보여지는 방식도 추가하여 사용자가 목록에서 더 많은 정보를 볼 수 있도록 하고자 합니다.
    • 검색 기능을 통해 소유한 책 중에서 원하는 책을 빠르게 확인할 수 있도록 합니다.
    • 즐겨찾기 기능을 추가하여 선택한 책을 더 빠르게 확인하거나, 개인 맞춤 추천에 활용될 수 있도록 합니다. 카테고리 역시 비슷하게 활용됩니다.
    • 예시:
      • 3단 그리드 방식이 아닌 일반적인 리스트 방식을 통해 목록에서 더 많은 정보를 확인할 수 있도록 하기
      • 즐겨찾기한 책을 최상단에서 우선적으로 보여주기
      • 검색을 통해 내가 해당 책을 소유했는지 빠르게 파악하기.

서비스 소개 영상

https://youtu.be/R0PwTJHG2uo

서비스 및 팀 문의 정보

About

책냥이 서비스 iOS 앱 레포지토리

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 5

Languages