[iOS | Swift] 제 1회 빡코딩콘 참여 후기

Minji Kim·2022년 5월 1일
0

해커톤

목록 보기
1/1
post-thumbnail

유튜버 개발하는 정대리배 해커톤인 제1회 빡코딩콘이 2022.4.28 ~ 2022.5.1(4일) 동안 진행되었다. 주제는 메모 서비스고 앱, 웹 상관없지만 나는 iOS 앱으로 개발했다.

요구사항

  • 화면구성
    • 메모 목록 화면
    • 메모 상세화면
    • 메모 편집, 작성 화면
  • 기능
    • 사용자는 작성한 메모 목록을 볼 수 있어야 함
    • 메모 목록에 노출되는 메모는 작성된 메모 문장 한 줄만 노출된다.
    • 메모 작성 페이지에서 메모 작성이 가능하다.
    • 메모를 작성할 때 작성된 메모의 글자 수가 노출된다.
    • 사용자는 메모를 검색할 수 있어야 한다.
    • 사용자는 메모를 편집할 수 있어야 한다.
    • 사용자는 메모를 삭제할 수 있어야 한다.
    • 작성된 메모는 비밀 메모로 변경이 가능하다.
  • 비밀메모
    • 메모 목록에 메모 문장이 노출되지 않는다.
    • 메모 목록 화면에는 “비밀 메모 입니다” 혹은 잠금 표시로 노출된다.
    • 메모 목록에서 상세 보기 클릭 시 비밀 메모인 경우 암호를 입력해야 메모 상세 화면으로 이동이 가능하다.
    • 일반 메모는 메모 상세화면에서 비밀 메모로 변환이 가능하다.
    • 일반 메모에서 비밀 메모로 설정 시 비밀번호 입력창이 뜨고 비밀번호를 입력하면 비밀 메모로 바뀐다.
  • 위 요건들 포함 추가 기능 및 화면 자유롭게 추가 가능

결과물

OS: iOS
Target: iOS 14.1 or later, only iPhone
Language: Swift
Architecture: MVP
Features: No Storyboard, UIKit, SwiftLint, UserDefaults, Git, Figma, Custom Font
External Libraries: SnapKit, Toast
GitHub Repository: https://github.com/minji0801/Memo

회고

원래 메모 목록 화면의 왼쪽 상단에 메뉴 버튼을 배치하여 검색과 설정화면으로 이동하도록 설계했다. 하지만 개발하다 보니 굳이 검색 화면으로 이동하는 프로세스를 1개 더 추가하는 것보단 기존 화면에서 바로 검색하는 게 더 편리할 것 같아서 수정했다.

설정 화면에서는 버전 정보, 글씨체 변경 등의 기능을 지원하고 싶었으나 다른 할 일이 많이 쌓여있는 터라 제외했다.(너무 아쉽다..ㅠ)

그리고 UITableViewCell을 슬라이드 해서 메모를 삭제하고 잠그도록 설계했지만 삭제만 구현했다. 잠그는 것은 수정 화면을 통해 변경하도록 했다.

메모 상세 화면은 진입할 때 비밀 메모라면 내용을 보여주지 않고 암호를 입력하도록 설계했으나, 사용자가 암호 입력을 취소하면 다시 메모 목록 화면으로 돌아가야 하기 때문에 메모 목록 화면에서 암호를 입력한 후에 암호가 맞으면 이동하는 것으로 구현했다.

원래 메모 상세 화면에서도 비밀 메모로 변경할 수 있도록 설계했는데, 메모 잠금은 수정 화면에서만 변경할 수 있도록 구현했다.

그림에 자물쇠 버튼을 깜빡했지만 메모 작성(수정) 화면은 설계한 대로 구현했다.

코드 리뷰

이 부분은 메모 작성 화면에서 체크 버튼을 클릭하여 메모를 저장하는 부분이다. 코드를 작성할 때도 어떻게 해야 최대한 덜 복잡하게 보일까 고민했던 부분이다. 다시 보니 아쉬운 부분이 보였다.

아래 코드에 주석으로 표시한 부분을 보면 동일 조건의 if else 문이 두 번 반복된다. 물론 이 둘을 합치면 if, else 문에서 각각 memo 상수를 만들어야 하지만 지금보단 깔끔해질 것 같다.

// 수정 전
func didTappedSaveRightBarButton(_ content: String?) {
    guard let content = content else { return }

    if content.isEmpty {
        viewController?.showSaveAlertViewController()
    } else {
        var id: Int
        if isEditing {	// 여기 if else문과
            id = memo.id
        } else {
            id = userDefaultsManager.getMemoId()
        }

        let memo: Memo = Memo(id: id, content: content, password: memo.password, isSecret: memo.isSecret)

        if isEditing {	// 여기 if else문의 조건이 똑같다.
            userDefaultsManager.editMemo(id, memo)
        } else {
            userDefaultsManager.setMemo(memo)
            userDefaultsManager.setMemoId()
        }
        viewController?.popToRootViewController()
    }
}

사람마다 다르겠지만 내가 봤을 땐 위에 보단 깔끔해진 느낌이 든다.

// 수정 후
func didTappedSaveRightBarButton(_ content: String?) {
    guard let content = content else { return }

    if content.isEmpty {
        viewController?.showSaveAlertViewController()
        return
    }
    
    var id: Int
    var newvalue: Memo

    if isEditing {
        id = memo.id
        newvalue = Memo(id: id, content: content, password: memo.password, isSecret: memo.isSecret)
        userDefaultsManager.editMemo(id, newvalue)
    } else {
        id = userDefaultsManager.getMemoId()
        newvalue = Memo(id: id, content: content, password: memo.password, isSecret: memo.isSecret)
        userDefaultsManager.setMemo(newvalue)
        userDefaultsManager.setMemoId()
    }

    viewController?.popToRootViewController()
}

이 부분은 암호 입력 Alert 창에서 확인 버튼을 눌렀을 때 실행되는 부분이다. 여기는 if 문 중첩이 많아서 코드 블록이 깊다. 좀 더 깔끔하게 정리할 수 있을 것 같다.

// 수정 전
func didTappedConfirmButton(_ password: String?) {
    guard let password = password else { return }

    if password.isEmpty {
        viewController?.updateMessageLabel(isEmpty: true)
    } else {
        if isChecking {
            if password == memo.password {
                viewController?.dismiss()
                NotificationCenter.default.post(name: NSNotification.Name("ShowMemo"), object: memo)
            } else {
                viewController?.updateMessageLabel(isEmpty: false)
            }
        } else {
            viewController?.dismiss()
            NotificationCenter.default.post(name: NSNotification.Name("InputPassword"), object: password)
        }
    }
}

별로 크게 바꾼 건 없지만 그래도 위에 보단 보기 편해진 것 같다.

// 수정 후
func didTappedConfirmButton(_ password: String?) {
    guard let password = password else { return }

    if password.isEmpty {
        viewController?.updateMessageLabel(isEmpty: true)
        return
    }

    if isChecking {
        if password == memo.password {
            viewController?.dismiss()
            NotificationCenter.default.post(name: NSNotification.Name("ShowMemo"), object: memo)
        } else {
            viewController?.updateMessageLabel(isEmpty: false)
        }
    } else {
        viewController?.dismiss()
        NotificationCenter.default.post(name: NSNotification.Name("InputPassword"), object: password)
    }

}

아! 그리고 LaunchScreen이 너무 빨라 없어져서 AppDelegate의 didFinishLaunchingWithOptions 메소드에 sleep을 추가했다.

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    sleep(1)	// 추가
    return true
}

제출한 결과물은 Android > iOS > Web 순으로 많은 것 같다. iOS에서도 SwiftUI를 사용한 사람도 있고, MVVM으로 개발한 사람도 있었다. 다른 사람의 결과물과 비교하면서 보면서 자극도 받고 되돌아보는 시간을 가졌다. 정말 유익한 이벤트였고 제2회 빡코딩콘이 열리면 또 참여할 것이다. 그땐 더 멋있게 구현해야지~

profile
iOS Developer

0개의 댓글