본문 바로가기
👨‍💻 프로그래밍/🍎 iOS 개발

🍎 Tipkit을 사용해서 앱의 숨겨진 기능을 유저에게 넛지 주기

by 개발자 진개미 2024. 9. 23.
반응형

TipKit이 뭐고 꼭 필요할까?

  • iOS 17부터 사용 가능한 앱을 쓰면서 새로운 기능, 숨겨진 기능, 꿀팁들을 슬쩍 알려주는 UI를 띄워주는 Framework입니다.
  • 아래와 같이 리스트를 꾹 눌러서 순서를 조정할 수 있는 건 보통 알기 힘든 경우가 많기 때문에 슬쩍 알려주는 형식입니다.

  • 물론 이걸 직접 구현할 수도 있습니다. Tooltip 정도는 간단한 UI이니 공수도 그렇게 많이 들지 않겠죠? 하지만 Tipkit에서는 저 Tip 언제 어떤 조건으로 보여줘야 하는지, 너무 많은 팁이 노출되면 유저가 피로하니 너무 많이 노출되지 않게 조절하는 등의 편리한 추가 기능이 있어서 굳이 안 쓸 이유는 없습니다.

너무 과하게 쓰면 안 됨! 😵

애플의 Human Interface Guideline을 보면 Tipkit의 역할과 주의해야 할 점들을 알 수 있습니다.

 

Offering help | Apple Developer Documentation

Although the most effective experiences are approachable and intuitive, you can provide contextual help when necessary.

developer.apple.com

 

한 마디로 여기에는 짧은 꿀팁만 넣어! 입니다. 너무 긴 정보나 팁이 아닌 경고 문구 등은 넣지 말고 빠르게 읽고 쉽게 이해할 수 있는 정보들을 넣어서 유저에게 가치를 주라는 의도입니다. (Quick, Instructional, Easy to Understand)


Tipkit의 전체적인 구조

🐜 Tip 정의하기

우선 Tip이라는 Protocol이 있습니다. 여기서 Tip에서 보여 줄 정보의 title, message, image와 언제 tip을 보여줄 것인지에 대한 규칙 (rules)를 정의합니다.

struct ExampleTip: Tip {
    var title: Text {}
    var message: Text? {}
    var image: Image? {}
    var rules: [Rule] {}
}

 

🐜 Tips로 여러 설정하기

이런 팁들을 여러개 정의하면 이걸 어떻게 보여줄 것인지 설정할 수 있는 Tips 객체가 있습니다. 여기서...

  • Tip을 어느 주기로 보여 줄 것인지 (계속, 매일, 매주, 매월 등)
  • Tip을 보여주기 위한 조건의 달성 여부나 언제 보여줬음 등의 정보를 어디에 저장할 것인지

등을 설정합니다.

try? Tips.configure([
    .displayFrequency(.immediate),
    .datastoreLocation(.applicationDefault)
])

 

🐜 UI에서 Tip 보여줄 부분에 추가하기

그러면 이제 UI의 어떤 부분에 Tip을 보여줄 것인지 설정할 수 있습니다. 크게 .popoverTip()TipView가 있는데 이는 밑에서 자세히 설명해 드리겠습니다.

 

🐜 유저가 원하는 동작을 하면 Tip에 이벤트로 알려주기

이제 Tip이 어떻게 생겼고 언제 보여줄지, 어디에 보여줄지, 어느 정도 주기로 보여줄지는 정의가 끝났으니 실제 앱에서 특정 행동을 했을 때 이벤트를 기부해서 (donate)해서 Tip Protocol이 규칙으로 Tip을 보여줄지 말지 판단할 수 있게 해야 합니다.

뭔 말이냐 하면, 유저가 이미 특정 기능을 잘 쓰고 있는데 그걸 팁으로 알려 줄 필요는 없으니 (오히려 앱을 쓰는데 방해될 테니) 이런 동작을 하면 팁을 안 보여주게 해야 합니다. 또, 유저가 특정 기능을 많이 쓰지도 않는데 그거에 관한 팁을 알려 줄 필요는 없으니 많이 쓸 때만 알려줄 수 있도록 특정 기능을 쓸 때마다 이벤트를 기부해서 이걸 몇 번 이상 한 경우에만 팁을 보여주자!라는 식으로 설정할 수 있게 해야 합니다.


TipKit 사용법

사용법을 익히는데는 직접 해 보는 게 최고라고 생각합니다. 그래서 제 앱에서 실제 TipKit을 어떻게 썼는지 예제와 함께 알려 드리겠습니다.

저는 일단 Swipe해서 수정 삭제가 가능한데 이걸 모르는 유저도 있을 거 같아 이걸 TipKit으로 보여주기로 했습니다.

 

위에서 말씀 드렸다 싶이 사실 수정/삭제를 많이 안 하시는 분들이나 이미 Swipe로 수정 삭제를 하는 분들에게 굳이 이 Tip을 보여 줄 필요는 없기 때문에 2가지 규칙을 정했습니다.

  1. Swipe 해서 수정/삭제를 1번도 사용한 적 없어야 함
  2. Detail에 들어가서 번거롭게 수정/삭제를 3번 이상 해야 함

 

그럼 Tip Protocol 정의부터 시작해 보겠습니다.

import TipKit

struct SwipeToDeleteTip: Tip {
    static let editOrDeleteFromDetailViewEvent = Event(id: "editOrDeleteInDetailView")
    
    var title: Text {
    	Text("왼쪽으로 밀어서 간편하게 수정/삭제할 수 있어요.")
    }
    
    var image: Image? {
    	Image(systemName: "trash.circle.fill")
    }
    
    var rules: [Rule] {
        // 상세 페이지에서 수정 삭제를 3번 이상 해야 함
        #Rule(Self.editOrDeleteFromDetailViewEvent) { event in
        	event.donations.count >= 3
        }
    }
}
  • Swipe 해서 수정/삭제 이벤트를 추가해 유저가 해당 동작을 할 때마다 기록할 예정입니다.
  • title과 image는 부드러운 말투와 도움이 되는 이미지로 간단히 만들었고,
  • 2번째 규칙을 rules에 구현했습니다. 1번째 규칙은 1번만 해도 끝이기 때문에 따로 기록하지 않고 바로. invalidate()를 써서 Tip을 없앨 생각입니다.

 

이제 이 Tip을 어디 UI에서 보여줄지 설정해야 합니다. 간단히 2종류만 추가하겠습니다.

// 리스트의 맨 위에 보여줌
List {
    TipView(SwipeToDeleteTip())
    
    ForEach(expenses) { expense in
    	ExpenseListRow(expense)
    }
}
// Tooltip 형태도 추가
List {
    ForEach(creditCards) { creditCard in
        CreditCardListRow(creditCard)
        	.popoverTip(SwipeToDeleteTip())
    }
}

 

다음으로 이벤트가 발생하는 모든 곳에서 알려 줘야 합니다. 우선 Swipe 해서 수정 삭제를 하는 모든 곳에서. invalidate()를 호출해 Tip을 안 보여 주도록 처리하겠습니다.

private func performSwipeToEdit() {
    SwipeToDeleteTip().invalidate(reason: .actionPerformed)
    
    // 나머지 수정하는 코드
}

private func performSwipeToDelete() {
    SwipeToDeleteTip().invalidate(reason: .actionPerformed)

    // 나머지 삭제하는 코드
}

 

그리고 상세 페이지에 가서 번거롭게 수정/삭제를 한 경우는 Event를 donate 하겠습니다.

private func performEdit() {
    Task {
        await SwipeToDeleteTip.editOrDeleteFromDetailViewEvent.donate()
    }
    
    // 나머지 수정하는 코드
}

private func performDelte() {
    Task {
        await SwipeToDelteTip.editOrDeleteFromDetailViewEvent.donate()
    }
    
    // 나머지 삭제하는 코드
}

 

마지막으로 앱이 열릴 때마다 Tip을 세팅하겠습니다.

private func setupTips() {
    try? Tips.configure([
        .displayFrequency(.daily),
        .datastoreLocation(.applicationDefault)
    ])
}

참고

 

Make features discoverable with TipKit - WWDC23 - Videos - Apple Developer

Teach people how to use your app with TipKit! Learn how you can create effective educational moments through tips. We'll share how you...

developer.apple.com


반응형