APP-iOS3rd / PJ3T2_Mymory

멋쟁이사자처럼 iOS 앱스쿨 3기 팀 프로젝트
11 stars 3 forks source link

:fire: Tag기능 고도화 #260

Closed iAmSomething closed 8 months ago

iAmSomething commented 8 months ago

PR 가이드라인

PR Checklist

PR 날릴 때 체크 리스트

PR Type

어떤 종류의 PR인가요?

연관되는 issue 정보를 알려주세요

Issue Number: N/A

PR 설명하기

Tag 기능을 고도화했어요!

여러분들도 그렇고 저도 직접 사용할 때 태그 목록 자체가 공감되지 않는 경우가 있었어요

그래서 firebase server에 등록한 뒤 관리하는 아이디어를 생각했는데, 사용자들이 직접 추가할 수 있으면 좋겠다는 생각이 들어서

tag 정책을 고도화하고 개발 대응 했습니다.

어떻게 작동하나요? code 기반으로 설명해주세요

// 태그 관리하는 Struct입니다.
struct TagCount: Identifiable, Codable {
    @DocumentID var id: String?
    var count: Int
}
// Tag 관리하는 Service를 싱글톤으로 따로 만들었어요!
final class TagService: ObservableObject{
    static let shared = TagService()
    let storage = Storage.storage()
    var tagList: [String] = []
    init() {
        Task {
            await loadTagList()
        }
    }
   // 메인액터를 통해서 우선순위를 높였습니다.
    @MainActor
    private func updateTagList(_ newValue: [String]) {
        if newValue.count < 15 {
            self.tagList = newValue.reversed()
        } else {
            self.tagList = Array(newValue.reversed()[0..<15])
        }

    }
// 새로 태그를 추가할 때 사용되는 함수에요! postView에서 태그를 선택해서 selected되면 동작합니다.
    func addNewTag(_ newValue: String) async {
        do {
            var newTag = TagCount(id: newValue, count: 0)
            let current = try await COLLECTION_TAG.document(newValue).getDocument()
            if current.exists {
                if let tag = try? current.data(as: TagCount.self) {
                    newTag = TagCount(id:tag.id, count: tag.count + 1)
                }
            }
            if newTag.count == 0 {
                // 새로운 tag 업로드
                try await COLLECTION_TAG.document(newValue).setData(from: newTag)

            } else {
                //이미 있는 tag 업데이트
                try await COLLECTION_TAG.document(newValue).setData(from: newTag, merge: true)
            }
            await loadTagList()
        } catch {
            print("태그 추가에 실패했습니다: \(error.localizedDescription)")
        }
    }
// 새로 태그를 삭제할 때 사용되는 함수에요! postView에서 태그를 선택해서 deselect되면 동작합니다.
// deselect될 때 tagCount가 0이어도 태그 목록에서 삭제하지는 않았어요. 데이터가 많아지면 자연스럽게 0개인 태그가 15개 우선순위에서 탈락할거라고 생각합니다.

    func deleteTag(_ tagStr: String) async {
        var newTag = TagCount(id: tagStr, count: 0)
        do {
            let tagCount = try await COLLECTION_TAG.document(tagStr).getDocument()
            if tagCount.exists {
                if let tag = try? tagCount.data(as: TagCount.self) {
                    if tag.count > 0 {
                        newTag = TagCount(id:tag.id, count: tag.count - 1)
                    }
                }

            }
            if newTag.count == 0 {
                // 새로운 tag 업로드
                try await COLLECTION_TAG.document(tagStr).setData(from: newTag)

            } else {
                //이미 있는 tag 업데이트
                try await COLLECTION_TAG.document(tagStr).setData(from: newTag, merge: true)
            }
            await loadTagList()

        } catch {
            print("태그 변경에 실패했습니다: \(error.localizedDescription)")
        }
    }
    private func loadTagList() async {
        do {
            let docs = try await COLLECTION_TAG
                .order(by: "count")
                .getDocuments()
            var tagList:[TagCount] = []
            for doc in docs.documents {
                guard let tag = try? doc.data(as: TagCount.self) else {return}
                tagList.append(tag)
            }
            let res: [String] = tagList.filter{$0.id != nil}.map{$0.id!}
            await updateTagList(res)
        } catch {
            print("태그 목록을 불러오는 데 실패했습니다: \(error.localizedDescription)")
        }
    }
}

가능하다면 추가해주세요

변경 사항 스크린샷 혹은 화면 녹화

https://github.com/APP-iOS3rd/PJ3T2_Mymory/assets/38745420/719fb422-71e5-404c-8e84-634eb08cd638

Test 여부

Test 정보

//예시
let testDatas: [TestData] = [.init(...),...]

기타 언급해야 할 사항들