본문 바로가기
iOS

[Swift] 반려동물 일기 앱 기획 [데이터 정의] - 2

by 워뇨옹2 2025. 7. 10.
728x90
반응형

지난 포스팅을 올리고나서 아리는 화장을 해주고

간소하게 장례식을 해줬습니다.

 

막 동물 장례식장을 예약하고 그런건 아니고,

화장한 가루를 나무에 뿌려주고 

아리가 좋아했던 과자랑 곡식들을 조금

뿌려줬습니다.

 

이제 아플 필요도 없고 잘 지내겠죠 ㅎㅎ

데이터 정의

지난 포스팅에서 해당 프로젝트를 시작하게 된 계기와

대략적인 기능들을 기획하고 정의했습니다.

 

이번에는 기획된 기능들을 기반으로 

앱에서 사용될 데이터들, 즉 모델을 정의해보려고 합니다.

 

최대한 간단하면서도 반려동물과의 기억을

남기기에 최적화 된 데이터들을 정의해보려고 합니다.

 

시작부터 복잡하게 갔다가 결국 완성도 못하고 

부러지는 경우를 수두룩하게 봤기에... 일단 완성에

목적을 두고 데이터를 정의해봅시다.

Profile

첫 번째 모델인 프로필 데이터 모델입니다.

사용자의 정보를 저장하기 위함이에요.

 

보통 서버에서는 users 라는 테이블을 두고 많이

사용하죠. 그래서 처음에는 user로 네이밍을 할까

했지만, 그냥 프로필로 정의하기로 했어요.

 

유저 아이디, 비밀번호, 개인정보, 이런게

들어있는것도 아니고 그냥 사용자의 간단한

이미지와 이름등만 저장할거라, 나중에 서버가

생기게 되면 다시 생각해보기로 하고 이렇게 갑시다.

struct Profile: Codable {
    let id: String
    let name: String
    let createdAt: Date
    let lastUpdatedAt: Date
}

FamilyMember

이번에는 동물의 프로필로 정의될 FamilyMember라는 데이터입니다.

사실 이 부분에 대해서 좀 많이 고민을 했어요.

 

그냥 Pet 혹은 PetProfile라고 이름을 지을수도 있었고

실제로 그렇게 코드를 썼는데, 뭔가 정도 없고

특색이 없어서 마음에 들지 않더라구요.

 

또 반려동물을 키우시는 분들은 공감하시겠지만,

우리가 반려동물이라고 부르는 이유부터가

단순히 같이 사는 동물이 아니라 가족의 일원이고

함께 우리 일상을 살아가는 존재들이기 때문이죠.

 

그래서 결국 FamilyMember로 이름을 짓게 되었습니다.

구성은 다음과 같아요.

struct FamilyMember: Codable {
    let id: String
    let name: String
    let since: Date
    let birthDate: Date
    let type: Species
    let sex: Sex
    let bio: String
    let createdAt: Date
}

내부에 Species, Sex라는 타입이 있는데 이건

Enum타입으로 정의를 해뒀어요.

enum Sex: String, Codable {
    case male
    case female
}

enum Species: String, Codable {
    case bird
    case dog
    case cat
    
    func emoji() -> String {
        return switch self {
        case .bird:
            "🐦"
        case .dog:
            "🐶"
        case .cat:
            "🐱"
        }
    }
}

동물 종에 대해서는 아직 완성을 못한 상태에요.

일반적으로 많이 키우는 개, 고양이가 있고,

제가 키웠고 키우고 있는 새 말고는 종을 어떻게

분류해야할 지 잘 감이 안 잡히더라구요🥲

좋은 아이디어가 있다면 추천해주시면 너무 감사하겠습니다.

 

하여튼 동물의 프로필은 이렇게 정의하기로 했습니다.

이미지는?

프로필이라고 하면 자고로 프로필 이미지가 들어가기 마련이죠.

이건 어떻게 처리할까 하다가 Document폴더에 해당

프로필 id를 파일 이름으로 하는 이미지 파일을 저장하기로 했습니다.

 

예를 들어 id = id1 이라고 한다면,

FamilyMemberImage = DocumentFolder/MemberImages/id1.jpeg(or png)

ProfileImage = DocumentFolder/ProfileImages/id1.jpeg(or png)

 

형태로 저장해서 다음과 같이 이미지 경로를 불러오기로 했습니다.

var imageUrl: URL? {
    guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
        return nil
    }

    let folderURL = documentsDirectory.appendingPathComponent("ProfileImages")
    let fileURL = folderURL.appendingPathComponent("\(id).\(fileExtension)")
    
    return fileURL
}

이렇게 하면 이전 프로필 이미지 내역은 저장할 수 없지만,

단순 일기장앱에서 이전 프로필 내역까지 저장할 필요는

없다고 생각했고 이 간단한 형태의 저장 방식을 채택하게 됐습니다.

Story

마지막은 해당 앱의 핵심이 되는 Story라는 데이터입니다.

앞선 포스팅에서 언급했듯, Diary가 아니라 Story로 정했습니다.

 

일기라고 하면 하루하루에 있었던 일들을 전체적으로

담아내는 것이지만, 제가 원하는건 순간순간에 있었던

일들을 이 앱에 누적해서 담아 하나의 이야기 책 같은

형태로 보존되어가길 원했어요!

 

구조는 다음과 같아요.

struct Story: Codable {
    let id: String
    let caption: String
    let createdAt: Date
    let mediaContentIds: [String]
    let songId: String?
    let lat: Double?
    let lng: Double?
    let taggedMemberIds: [String]
}

Diary가 아닌 Story가 된 만큼 title을 넣을 지 말지

고민을 했는데, 별로 필요가 없을 것 같았어요.

 

또 이 모델은 인스타그램의 영향을 받았는데,

Story라고 지어놓고 보니 인스타그램에 스토리가

있다는걸 깨닫게 되어버립니다.😅

 

인스타그램 사용하지도 않는데, 이거 알아보겠다고

계정하나 만들어서 이것 저것 많이 건드려봤어요.

 

아직 UX / UI 까지 디테일하게 들어가지는 않았지만,

위 모델을 기반으로 인스타그램 포스트와 스토리를

적당히 섞은 형태의 UX로 인터페이스를 구성하게 

될 것 같아요.

 

이미지와 동영상 파일은 고유의 id를 파일명으로 해서

다음 경로로 저장하려고해요.

 

DocumentFolder/Stories/{storyId}/[mediaContentId.mp4 jpeg png...]

 

또 앞서 학습하고 포스팅했던 MusicKit을 기반으로 

음악도 포함할 수 있게 songId를 추가했답니다!

 

location과 관련된 부분은 어떻게 해야할 지 아직

명확히 정하지는 않았지만, MapKit을 사용하는 방향으로

갈텐데 toponym(지명) address(주소) 정보도

저장할지 말지 고민 좀 해보겠습니다.

 

이렇게 해서 3개의 모델로 앱을 구성하게 되었습니다.

개발을 진행하면서 더 추가되고 제거되는 부분들이 있겠지만,

일단은 이 포스팅을 기반으로 진행을 해보겠습니다.

 

다음편에 계속 총총

728x90
반응형