Skip to content

Conversation

@OneTen19
Copy link
Member

🌴 작업한 브랜치

style/#187

✅ 작업한 내용

MyCertificationComponent를 만들었습니다
마이페이지와 홈에서 사용되는 컴포넌트라서 Global 폴더 내에 Components에 만들었습니다.

스크린샷 2025-11-23 오전 2 22 22 스크린샷 2025-11-23 오전 2 22 40 스크린샷 2025-11-23 오전 2 23 01
        // case 1: 취득 예정, 버튼 없음
        MyCertificationComponent(
            type: .expected(location: "고양시", time: "09:00"),
            title: "정보처리기사",
            category: "국가기술자격",
            description: "소프트웨어 개발 관련 자격증으로, 계획수립, 분석, 설계, 구현...",
            actionConfig: .viewOnly
        )
        
        // case 2: 취득 예정, 버튼 있음
        MyCertificationComponent(
            type: .expected(location: "서울시", time: "14:00"),
            title: "정보보안기사",
            category: "국가기술자격",
            description: "소프트웨어 개발 관련 자격증으로, 계획수립, 분석, 설계, 구현...",
            actionConfig: .editable(onEdit: {
                print("수정")
            }, onDelete: {
                print("삭제")
            })
        )
        
        // case 3: 취득 완료, 버튼 없음, 점수 있음
        MyCertificationComponent(
            type: .completed(date: "2023. 11. 23", score: "IM3"),
            title: "OPIC",
            category: "어학",
            description: "소프트웨어 개발 관련 자격증으로, 계획수립, 분석, 설계, 구현...",
            actionConfig: .viewOnly
        )
        
        // case 4: 취득 완료, 버튼 있음, 점수 없음
        MyCertificationComponent(
            type: .completed(date: "2023. 11. 23", score: nil),
            title: "OPIC",
            category: "어학",
            description: "소프트웨어 개발 관련 자격증으로, 계획수립, 분석, 설계, 구현...",
            actionConfig: .editable(onEdit: {
                print("수정")
            }, onDelete: {
                print("삭제")
            })
        )

이런 식으로 사용하면 되고, 명세서가 나오면 date나 time같은 건 String이 아니라 조금 더 깔끔하게 관리하는 방향으로 개선할까 고민하고 있슴다. 아직은 안나와서 그냥 UI 구현만 하려고 String으로 해놨어요

❗️PR Point

  • 네이밍이 너무 안떠올라서 일단 지금처럼 해놨는데 네이밍 좀 추천해주세요.. MyCertificationComponent 너무 구림 ㅜ

  • 그리고 ActionConfig enum 명도 좀 구린데 졸려가지고 머리가 잘 안돌아가서 일단 냅뒀어요

  • 수정과 삭제 액션의 경우 결국 API 요청을 담당하게 될 텐데 여기에 async/await 을 붙여야 할까요? 요즘 콩코롱시 공부하는 중이라 이런 게 자꾸 눈에 걸리네요. 함 고민해보고 의견 주시면 조을듯

  • 커밋하는 거 깜빡했어요.. ㅠㅈㅅ

📸 스크린샷

기능 스크린샷
GIF

📟 관련 이슈

@OneTen19 OneTen19 added this to the [CERTI] 1차 스프린트 milestone Nov 22, 2025
@OneTen19 OneTen19 self-assigned this Nov 22, 2025
@OneTen19 OneTen19 added Style 🖼️ UI 작업 한열 🧄 한열 작업 labels Nov 22, 2025
Copy link
Contributor

@sangyup12 sangyup12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네트워크 요청은 무조건 비동기 처리해야한다고 생각해요. UI 렌더링은 메인스레드에서만 진행되는데 비동기처리를 하지 않으면 네트워크 응답을 기다려야 해서 UI가 버벅이게 되잖아요. 사용자 경험이 너무 떨어질 거 같아요. async/await을 안 쓰는 상황은 어떤 상황이 있을까요?


import SwiftUI

struct MyCertificationComponent: View {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3 이름추천
MyCertificationStatusCard 어떤가요? 우리 앱에 진짜 카드가 있어버려서 좀 그른가...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

흠 구리긴 구리네영.. 컴포넌트에 진짜 컴포넌트라는 단어를 넣어서 그런거 가타영
저거 CertificationCardList가 컴포넌트명이던데
MyCertificationCard나 MyCertificationItem 추천해봅니둥

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

진짜 카드가 따로 있어서 헷갈릴 수 있을 것 같긴 하네요
이미 충분히 헷갈리긴 하지만.. 일단 MyCertificationItem 으로 변경하겠습니다!

}
}

enum ActionConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3 이름추천
EditType 어떤가요?

Copy link
Contributor

@Yeonnies Yeonnies Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조은디?
(상엽시께 좋다는 의미)

private var topBadge: some View {
HStack(alignment: .center, spacing: 0) {
HStack(alignment: .center, spacing: 4) {
Image(systemName: "checkmark.circle.fill")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거슨 왜 SF symbols 사용했나여. 피그마에 흰배경에 파란체크 아이콘이 안 빠져있는 것 같네염

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞어요 피그마에 따로 안 빠져있어서 그냥 SF symbols 사용했습니다..
따로 요청할게유

Copy link
Contributor

@Yeonnies Yeonnies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니닷!

수정과 삭제 액션의 경우 결국 API 요청을 담당하게 될 텐데 여기에 async/await 을 붙여야 할까요?

혹시 질문에 대해 자세히 설명해주실 수 있으신가요?
async/await는 비동기 작업을 처리할 때 필요한 건데 수정과 삭제에 경우 네트워크 처리이기 때문에 당연히 비동기 작업이라고 생각해서 써야한다고 생각합니다..
질문하신 의도가 뷰에서 수정/삭제작업을 할 경우 모달이나 알림창이 떠서 나중에 처리해도 되는 거 아니냐는 질문인건가요?? 아님 다르게 처리할 수 있는 방법이 있는 건가요?


import SwiftUI

struct MyCertificationComponent: View {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

흠 구리긴 구리네영.. 컴포넌트에 진짜 컴포넌트라는 단어를 넣어서 그런거 가타영
저거 CertificationCardList가 컴포넌트명이던데
MyCertificationCard나 MyCertificationItem 추천해봅니둥

}
}

enum ActionConfig {
Copy link
Contributor

@Yeonnies Yeonnies Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조은디?
(상엽시께 좋다는 의미)

@OneTen19
Copy link
Member Author

@sangyup12 @Yeonnies

네트워크 요청을 비동기처리 하는 이유가
상엽님이 말씀해주신 것처럼 메인스레드에서 작업하기엔 너무 오래 걸리는 작업이기에 swift concurrency에서는
await으로 메인스레드 점유권을 놓아주고 백그라운드 스레드에서 작업을 진행하는 것으로 알고 있어요!

결국 오래걸리는 네트워크 작업을 메인 스레드에서 작업할 경우 유저의 입장에서는 앱이 멈춘 것 같은 안 좋은 UX를 느끼게 되기 때문에 비동기 처리를 해줘서 매끄러운 UI 변화를 추구함으로써 유저에게 좋은 UX 경험을 주기 위함이라고 생각하는데,

수정과 삭제라는 케이스에도 백그라운드 스레드에서 처리하고 메인스레드에서는 계속 UI변화를 그리는 게 맞나? 하는 고민이 들었어요.

예를 들어 수정의 경우 서버로 수정 요청을 보낸 후 바로 메인 스레드를 놓아주게 되면
수정 요청을 반영하는 작업은 백그라운드에서 진행되고 있고, 그 외 작업들이 메인스레드에서 진행되며 UI 렌더링이 될 텐데
인터넷 속도이슈나 수정사항 양 자체가 많아서 수정작업이 좀 오래 걸릴 경우,
내가 변경한 수정사항은 반영이 되지 않은 상태로 UI가 그대로 그려져 있는 모습을 확인할 수 있겠다는 생각이 들었어요.

한 마디로 네트워크 요청 사항이 아직 반영되지 않은 모습을 유저가 확인하게 될 수도 있지 않을까? 라는 고민이에요.
자격증 리스트에서 한 가지 삭제버튼을 눌렀는데, 해당 자격증이 삭제되지 않고 탭 이동같은 상태변화를 통해 새로고침을 해야 수정사항이 반영되는 모습을 보게 되는 사이드 이펙트가 우려되더라구요.

그래서 이러한 네트워크 요청에 따른 즉각적인 UI 반영사항이 필요한 경우에는 다른 UI 변화를 멈추고 메인스레드에서 진행한 후 완료가 된 후에 UI를 그리는 게 좀 더 UX적으로 적합한 방향인가? 라는 의문이 있었습니다.
어떻게 생각하세요?

@sangyup12
Copy link
Contributor

삭제를 했는데 바로 지워지지 않고 새로고침을 해야되는 문제는 확실히 사용자에게 혼란을 줄 거라고 생각이 됩니다.

  1. 로딩 효과를 이용해보는 건 어떨까요?
    네트워크 요청을 비동기로 처리하고, 응답이 오기 전까지 로딩 애니메이션을 보여주면서 또 다른 화면 조작을 방지할 수 있습니다.
    그리고 요청이 끝나고 응답을 받고나서 로딩이 사라지고 화면을 렌더링 하는 방식입니다.
    사용자 입장에서 아무리 짧은 시간의 대기라도 화면이 느려지는 것보다 로딩 중이라고 확인이 되는 게 더 안정적인 서비스라고 느껴질 것 같아요.
    방금 직접 에타나 당근처럼 게시글이 있는 서비스에서 확인해봤는데 둘 다 작게 로딩 애니메이션을 보여주고 있더라고여. 속도가 빨라서 안 보일 때도 있었어요.

  2. 서버 응답을 기다리지 않고 UI를 업데이트?
    참고글:https://velog.io/@rosemin928/Optimistic-UI
    이걸 Optimistic UI라고 하더라구요. 좋아요 버튼처럼 즉각적인 반응이 필요한 곳에서 사용한다고 하는데 사실 데이터 수정 삭제에서는 롤백 로직도 더 디테일하게 필요할 것 같고 구현하기 어려울 것 같아요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Style 🖼️ UI 작업 한열 🧄 한열 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SCRUM-39] Style: 취득예정, 취득완료(수정 및 삭제 포함) 자격증 컴포넌트

4 participants