WWDC 24. AdAttributionKit 팩트만 정리

WWDC 24에서 AdAttributionKit은 정말 마이너한 주제죠. 그러나 애드 테크에게는 애플이 저승사자이므로, 밥그릇 지키기 위해 빨리 업데이트를 따라가야 해요. 이번 업데이트 팩트만 빡시게 정리할게요.

  1. 앱스토어와 서드파티 iOS 스토어 양쪽에서 모두 활용 가능하다
  2. 임프레션과 클릭 시그널을 기록하는 로직이 개선된다
  3. 리인게이지먼트 컨버전을 기록할 수 있다

공식 자료 먼저

설명 너무 좋아요

위 영상은 담당 엔지니어인 Nikhil Varma의 설명이에요. SKAN4 설명도 작년에 봤었는데 설명을 참 잘합니다. Apple Developer 공식 문서는 이래요.

  • AdAttributionKit Overview
    • Impression 구조체 - 광고 노출 & 광고 클릭이 발생한다는 정보를 앱이 애플에게 알려주는데 활용하면 되요
    • Postback 구조체- 앱을 설치한 유저가 앱에서 어떤 이벤트를 했는지에 대한 정보를 앱이 애플에게 알려주는데 활용하면 되요
      • PostbackUpdate 구조체 - Postback 구조체에 넣어줘야 할 값이에요

위에 불릿 포인트로 뼈대를 잡아드렸습니다. 길을 잃으면 안되요.

Fact 1 - AdAttributionKit은 앱스토어와 앱스토어가 아닌 iOS 스토어 양쪽에서 모두 활용 가능하다

공식문서 시작부터 보자구요. App Store와 alternative app marketplaces에서 동작한다고 되어있죠. AdAttributionKit이 처리하는 기능은 원래 App Store의 SKAdNetwork(줄여서 SKAN, 이름부터 SK로 시작하죠? StoreKit이기 때문입니다. 그래서 App Store 전용 기능인 것이구요.)이 해오던 것입니다. 2021년 SKAN이 나온 이래 지금은 SKAN4까지 업데이트가 되었죠.

???: 분명히 말했다 이게 무슨 기능인지. 나중에 다른 소리 하기 없기.

애플의 문제는 EU의 GDPR -> DMA가 미국의 빅테크들을 때려잡기 시작하고 App Store가 Gatekeepers 중 하나로 지정되면서 생겨요. EU에선 아이폰에 앱스토어가 아닌 다른 앱 마켓플레이스가 가능하도록 반드시 애플은 기술적인 조치를 해야하죠. 앱스토어 매출의 최소 십퍼센트 중반 최대 이십퍼센트가 EU에서 나온다는 추측이 있고, 이 시장에 진출하기 위해 Epic, Microsoft, Meta가 간을 보고 있습니다. 에픽은 그럴만한 역사가 있고, 세계 최대 게이밍 퍼블리셔 중 하나인 마이크로소프트는 역시 게이밍 web store 부터 시작한다고 발표를 하기도 했죠.

이런 대체 스토어에는 SKAN 자체가 적용되지 않기에, 애플은 SKAN 기능을 래핑한 AdAttributionKit을 만들어서 어떤 스토어든 모든 어트리뷰션을 iOS 레벨에서 개인정보가 보호되는 형태로 처리를 하겠다는 것입니다. SKAN은 여전히 앱스토어에서 활용 가능해요. 그래서 얼마간은 AdAttributionKit과 SKAN이 공존하게 될 것이고, 변화하는 상황에 맞게 애플이 교통정리를 하겠죠.

Fact 2 - 임프레션과 클릭 시그널을 기록하는 로직이 개선된다

비교적 최근에 링크드인에서 SKAN fraud에 대한 Nebojsa Radovic글이 이슈가 된적이 있어요. 이 주장은 기술적으로 엄밀한 의미에서의 fraud는 아니지만, 일부 눈 밝은 업계 종사자들이 대놓고 말하지 못했던 내용을 끄집어낸 것이 좋았죠. 참고로 업계 종사자라도 대부분 알지 못하는 내용이에요. 그러니 평소에 알고 지내던 카운터 파트를 너무 미워하지는 마시고, 요지는 다음과 같아요.

  • SKOverlay의 취약성
  • 이로 인해 클릭 아닌 클릭이 생기는데, SKAN은 클릭 룩백 윈도우가 너무 길다
  • 그래서 장기적으로 비정상적인 퍼포먼스를 보이는 SKAN 캠페인이 있고 이정도의 비정상이면 fraud 아니냐

무료 게임을 플레이하는 유저들은, 게임 플레이 중 광고를 보고 보상을 받으려고 할때, 지금 하고 있는 게임과는 다른 게임의 광고를 자주 보게 되는데 이때 SKOverlay를 만나게 되는 경우가 많아요. 광고물 위에 배너가 오버레이 되면서 다른 게임을 설치할 수 있는 작은 앱스토어 창이 열리죠. 아래 이미지 같은거에요.

source - https://rajeshbudhiraja5.medium.com/skoverlay-ios-29f373377381

SKOverlay 자체는 문제가 아니에요. 문제는 SKOverlay에 의해 이런 식의 배너가 표시되면, SKAN은 이것 자체를 클릭으로 인정해버려요. 자 기억을 더듬어보세요. 이런 배너를 만났을때 실제로 광고를 클릭했었나요? 아니면 일정 시간이 지나면 자동으로 배너가 표시되던가요? 뭐 클릭 없이도 클릭이 발생하는 이런 상황, 그리고 클릭이 없는데 SKAN에는 click-through 인스톨로 기록이 되는 이런 상황. 저는 이제 말을 아낄게요.

fidelity_type=0은 view-through로 간주한다. 그리고 StoreKit으로 렌더링된 광고는 view-through가 아니다. 그리고 SKOverlay는 StoreKit으로 렌더링된 광고이다.

AdAttributionKit은 다른 로직을 사용하고 있기 때문에 앞으로는 이런 문제가 발생하지 않을 것으로 보여요. 애플이 확실하게 개선한 부분이에요. Impression 구조체에 대한 설명에서 간단하게 언급이 되는데,

To support click through attribution, place a UIEventAttributionView over the ad content and call the handleTap() API once a person has tapped the ad content. The framework then validates that a person taps a UIEventAttributionView before recording the impression. The framework throws an error if it can’t validate a tap happened in a UIEventAttributionView.

handleTap()이 실제 사람이 탭을 한건지 아닌지 검증을 하고, 검증을 통과한 다음에서야 이 탭이 클릭으로 인정되게 구조를 짜놨네요. 훌륭합니다. 그래서 앞으로는 유저가 실제로 탭을 해야만 클릭 시그널이 잡힙니다.

한가지 중요한 개선사항이 더 있는데, 이렇게 광고 시그널을 기록하는 Impression 구조체가 초기화되기 위해서는 JWS(JSON Web Signature)가 필요하도록 업데이트 되었어요. 이는 애플 <> 광고를 서빙하는 애드 네트워크 사이의 프라이빗 인증키라고 보면 됩니다. 이 인증에 실패하면 네트워크가 발생시킨 클릭이나 임프레션을 애플이 인정하지 않습니다. 이 결과로 이번 클릭이나 임프레션은 어트리뷰트 될 수 없죠. 이런 인증과정을 통해서 애플은 연동된 네트워크 내에서 일부 참여자가 비정상적인 방식으로 클릭이나 임프레션을 만들어내는 시도를 걸러낼 수 있는 수단을 가집니다.

Fact 3 - 리인게이지먼트 컨버전을 기록할 수 있다

리인게이지먼트는 별도의 섹션에서 설명을 하기도 했죠. 지난 버전과 비교한다면 없던 기능이 생긴 것이고 애드 테크 환경에서 정말 원했던 기능이기도 하니까요. 마케팅과 관계 없는 분들은 이 용어가 생소할 수 있으니 설명을 덧붙입니다.

이미 앱을 단말기에 설치해 놓은 유저가, 마케팅에 의해 앱을 실행한다면, 우리는 이 유저가 리인게이지먼트 되었다 라고 보고 있어요. 앱을 단말기에 설치시키기 위한 마케팅과, 이미 있는 앱을 다시 사용하도록 만드는 마케팅이 전략적으로도 다르고 그 목표에도 차이가 있어서 이렇게 구분을 합니다.

리인게이지먼트 컨버전을 기록하기 위해서는, 우선 광고가 노출되는 지면에서 리인게이지먼트 시그널을 만들어내야 합니다. 앞에서 Impression을 만들때 JWS로 인증을 먼저 한다고 했죠? 이때 애플로 보내는 요청에 아래와 같이 eligible-for-re-engagementtrue 로 하면, 앞으로 발생할 클릭이 리인게이지먼트 시그널로 간주됩니다.

{
  "ad-network-identifier": "com.example.adNetwork",
  "advertised-item-identifier": 87234523587,
  "eligible-for-re-engagement": true,
  "impression-identifier": "12B08FE4-ABD2-4597-B3EB-DB3D8D83855D",
  "impression-type": "app-impression",
  "publisher-item-identifier": 92834928,
  "source-identifier": 2345,
  "timestamp": 1711556387300
}

eligible-for-re-engagement

그 후 실제로 광고 클릭이 발생할때 아래와 같이 reengagementURL 과 함께 handleTap() 을 호출하면 되는 것이죠. 이렇게 되면 iOS는 reengagementURL 에 입력된 Universal Links를 이용해서 그 앱의 특정 화면으로 유저를 이동시키고, 앱에는 이번 이동이 리인게이지먼트에 의한 것임을 의미하는 쿼리 파라미터를 붙여서 전체 링크 주소를 콜백합니다.

// Initiating re-engagement inside ad tap handler
func customAdViewTapped() async throws {
  if let reengagementURL = URL(string: "https://dv.example.com/promoOne") {
    try await appImpression.handleTap(reengagementURL: reengagementURL)
  } else {
    // Error Handling
  }
}

reengagementURL

만약 유저 단말기에 앱이 없어서 앱이 안열리면 어떻게 되냐구요? 그래서 Universal Links가 필요합니다. 이 유니버셜 링크를 잘 설정 한다면, 단말기에 앱이 없을때는 앱스토어로 이동해서 유저가 앱을 새로 설치할 수 있게 되요. 이렇게 설치된 앱이 실행이 되면, AdAttributionKit 는 이번 설치를 re-enengagement가 아닌 install로 간주하고 앞서 발생한 클릭도 install 캠페인의 클릭으로 간주하여 어트리뷰트 합니다.

팁을 하나 남기자면, iOS 클라이언트 개발자들도 유니버셜 링크를 잘 모르는 분들이 생각보다 많았어요. 코어 기능이 아니기 때문이었을텐데, 어찌되었든 MMP를 사용하는 광고주라면 MMP가 매우 반갑게 유니버셜 링크 구현을 도와줄 것이니 이쪽을 이용해보세요.

참고로 유니버셜 링크는 web server와 mobile application 사이의 two factor authentication 같은거에요. 구글이 만든 App Links도 마찬가지랍니다. 이 개념을 탑재하고 흐름을 잘 살펴보면 이해가 되실거에요.