카톡 아이콘이 공유 시트 하단에 2개 중복 노출되는 이슈 문의

현재 iOS 공유 시 카카오톡 아이콘이 하단 앱 아이콘 영역에 두 번 중복 노출되는 문제가 있어 문의드립니다. (스크린샷 초록 동그라미 부분 참고)

  • 기본 사항: SDK 최신버전 사용중이며, APP_ID : 1280964
  • 배경 설명: 현재 공유하기 시 카톡 템플릿을 사용하기 위해 템플릿 SDK 추가함.
  • 구현 방식: UIActivityViewController 사용 (Notes, Reminders 등 기본 앱 함께 노출됨)
  • 이슈 설명:
  1. 공유 시트 하단(앱 아이콘 영역)에 KakaoTalk 아이콘이 두 개가 중복 노출됩니다. 두 아이콘 중 어떤 것이 SDK 기반 공유인지 사용자가 구분할 수 없어 UX 혼란이 발생합니다.
  2. Apple의 excludedActivityTypes를 사용해봤는데 이미 빌트인 공유 아이템 (예: 에어드랍)만 제거가 가능하고, 다른 카톡 아이콘을 제거할 수 없는 상황입니다.
  3. id com.iwilab.KakaoTalk.Share 를 오버라이드 하려고 했는데 그러면 sdk 템플릿 카톡 아이콘이 앞에 노출되는 하는데 공유 방식이 이상합니다.
  • 문의 사항:
  1. KakaoTalk 아이콘이 하단에 중복 표시되지 않도록 제어할 수 있는 방법이 있을까요?

안녕하세요

재현 가능한 URL 제공 가능하실까요?

안녕하세요, 어떤 URL 을 드리면 될까요? 예시 주시면 감사하겠습니다

첨부하신 이미지는
SDK를 사용한 카카오톡 공유하기 기능이 아닌 OS가 제공하는 공유 기능 사용하신 것으로 보이는데요
이미지속 공유 기능 사용하신 URL 부탁드립니다.

아 넵넵, 참고로 첨부한 이미지에서 왼쪽은 시스템 제공 아이콘이고 오른쪽은 SDK 템플릿 공유 기능에 의해 제공된 아이콘입니다.
오른쪽 아이콘을 눌렀을 때 나오는 링크는 아래와 같습니다:

kakaolink://send?appver=8.7.2&template_id=4478&template_json=%7B%22P%22:%7B%22SNM%22:%22%EC%BF%A0%ED%8C%A1%22,%22L%22:%7B%22LA%22:%22market:%5C/%5C/details?id%3Dcom.coupang.mobile%22,%22LCI%22:%22kakaod9001304ad3b34b4f0eeb28912f099a0:%5C/%5C/kakaolink%22,%22LMO%22:%22https:%5C/%5C/coupang.com%22,%22LPC%22:%22https:%5C/%5C/coupang.com%22,%22LCA%22:%22kakaod9001304ad3b34b4f0eeb28912f099a0:%5C/%5C/kakaolink%22,%22LCM%22:%22kakaod9001304ad3b34b4f0eeb28912f099a0:%5C/%5C/kakaolink%22,%22LCP%22:%22kakaod9001304ad3b34b4f0eeb28912f099a0:%5C/%5C/kakaolink%22%7D,%22SIC%22:%22https:%5C/%5C/k.kakaocdn.net%5C/14%5C/dn%5C/btsPkwv5Dj5%5C/GDkSKqMa9qiyaE0Tpxy8p1%5C/o.jpg%22,%22FW%22:true,%22SDID%22:%224478%22,%22TP%22:%22Commerce%22,%22SID%22:%22capri_1280848%22,%22ME%22:%22$%7BME%7D%22,%22SL%22:%7B%22LMO%22:%22https:%5C/%5C/coupang.com%22,%22LA%22:%22market:%5C/%5C/details?id%3Dcom.coupang.mobile%22,%22LCA%22:%22kakaod9001304ad3b34b4f0eeb28912f099a0:%5C/%5C/kakaolink%22,%22LPC%22:%22https:%5C/%5C/coupang.com%22,%22LCM%22:%22kakaod9001304ad3b34b4f0eeb28912f099a0:%5C/%5C/kakaolink%22,%22LCI%22:%22kakaod9001304ad3b34b4f0eeb28912f099a0:%5C/%5C/kakaolink%22,%22LCP%22:%22kakaod9001304ad3b34b4f0eeb28912f099a0:%5C/%5C/kakaolink%22%7D,%22VA%22:%226.0.0%22,%22DID%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22,%22VW%22:%222.5.1%22,%22LA%22:%22market:%5C/%5C/details?id%3Dcom.coupang.mobile%22,%22VM%22:%222.2.0%22,%22RF%22:%22out-client%22,%22VI%22:%225.9.8%22%7D,%22C%22:%7B%22BUL%22:%5B%7B%22BU%22:%7B%22T%22:%22%E6%9F%A5%E7%9C%8B%E8%AF%A6%E6%83%85%22%7D,%22L%22:%7B%22LPC%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22,%22LMO%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22%7D%7D%5D,%22TI%22:%7B%22L%22:%7B%22LMO%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22,%22LPC%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22%7D,%22TD%22:%7B%22T%22:%22title%22%7D%7D,%22THL%22:%5B%7B%22TH%22:%7B%22W%22:400,%22H%22:400,%22THU%22:%22http:%5C/%5C/mud-kage.kakao.co.kr%5C/dn%5C/Q2iNx%5C/btqgeRgV54P%5C/VLdBs9cvyn8BJXB3o7N8UK%5C/kakaolink40_original.png%22%7D,%22L%22:%7B%22LMO%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22,%22LPC%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22%7D%7D%5D,%22CMC%22:%7B%22CP%22:0,%22DP%22:900,%22RP%22:1000,%22T%22:%22test%22,%22CU%22:%22unit%22,%22DR%22:90%7D%7D,%22K%22:%7B%22ti%22:%224478%22,%22ai%22:%221280848%22%7D%7D&linkver=4.0&template_args=%7B%22$%7BFIRST_BUTTON_WEB_URL%7D%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22,%22$%7BIMAGE_HEIGHT%7D%22:%22400%22,%22$%7BIMAGE_URL%7D%22:%22http:%5C/%5C/mud-kage.kakao.co.kr%5C/dn%5C/Q2iNx%5C/btqgeRgV54P%5C/VLdBs9cvyn8BJXB3o7N8UK%5C/kakaolink40_original.png%22,%22$%7BANDROID_EXECUTION_URL%7D%22:%22%22,%22$%7BFIRST_BUTTON_MOBILE_WEB_URL%7D%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22,%22$%7BDISCOUNT_RATE%7D%22:%2290%22,%22$%7BDISCOUNT_PRICE%7D%22:%22900%22,%22$%7BCURRENCY_UNIT_POSITION%7D%22:%220%22,%22$%7BIMAGE_COUNT%7D%22:%221%22,%22$%7BCURRENCY_UNIT%7D%22:%22unit%22,%22$%7BFIRST_BUTTON_IOS_EXECUTION_URL%7D%22:%22%22,%22$%7BIMAGE_WIDTH%7D%22:%22400%22,%22$%7BPRICE%7D%22:%221000%22,%22$%7BIOS_EXECUTION_URL%7D%22:%22%22,%22$%7BWEB_URL%7D%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22,%22$%7BMOBILE_WEB_URL%7D%22:%22https:%5C/%5C/link.coupang.com%5C/a%5C/cEXgyk%22,%22$%7BFIRST_BUTTON_TITLE%7D%22:%22%E6%9F%A5%E7%9C%8B%E8%AF%A6%E6%83%85%22,%22$%7BPRODUCT_NAME%7D%22:%22test%22,%22$%7BFIRST_BUTTON_ANDROID_EXECUTION_URL%7D%22:%22%22,%22$%7BTITLE%7D%22:%22title%22,%22$%7BFIXED_DISCOUNT_PRICE%7D%22:%22%22%7D&appkey=d9001304ad3b34b4f0eeb28912f099a0&extras=%7B%22iosBundleId%22:%22com.coupang.Coupang%22,%22KA%22:%22sdk%5C/2.21.1%20sdk_type%5C/swift%20os%5C/ios-17.4%20lang%5C/en-CN%20res%5C/393x852%20device%5C/iPhone%20origin%5C/com.coupang.Coupang%20app_ver%5C/8.7.2%22%7D

참고로, UIActivityViewController.excludedActivityTypes 는 카카오 공유 시스템 아이템을 삭제하지 못하는걸로 보여요. shareViewController.excludedActivityTypes = [UIActivity.ActivityType("com.iwilab.KakaoTalk.Share")] .
카카오 공유 시스템 아이콘을 없앨 수 있는 방법이 있을까요? 아니면 통합하는 방법이 있을까요?

전달해 주신 긴 텍스트는 카카오톡 공유하기의 커스텀 스킴으로 서비스가 이를 직접 activityItems로 전달되는 경우는 발생하지 않을 것으로 보이는데요 activityItems에 어떤 내용을 전달 하셨나요?

첨부 이미지의 표시 아이콘은 OS가 제어하기에 톡에서 아이콘 2개가 표시되게 설정하지는 않습니다.

도움주셔서 감사합니다!

Q1. activityItems에 어떤 내용을 전달 하셨나요?
A1. 참고로 저희가 쿼타가 걸려서 기본 포멧 + 템플릿 SDK을 둘 다 사용해야하는데:

  1. 현재 템플릿을 사용하지 않는 경우, activityItem 에서 “Pampers 2025 Air Chacha summer panty diapers
    https://link.coupang.com/a/b7D2QC” 이런식으로 전송을 하고 있습니다.
  2. 템플릿을 사용하는 경우는, UIActivity 를 수정하는데 사용자가 클릭하면 ShareApi.shareDefault(templatable:serverCallbackArgs:completion:) 즉, 카카오 sdk를 호출해서 스키마 kakaolink://send?xx 를 받고 그 다음에 카카오 앱을 열고 공유합니다.

Q2. 첨부 이미지의 표시 아이콘은 OS가 제어하기에 톡에서 아이콘 2개가 표시되게 설정하지는 않습니다.

시스템 공유 기능(UIActivityViewController)을 사용하고 카카오 공유 SDK를 연동하면 아이콘이 두 개 표시되나요? SDK 연동 시 UIActivityViewController를 사용하지 않고 공유 기능을 커스터마이징해야 하나요?

SDK를 사용할 때는 UIActivityViewController가 아닌 일반적인 UIApplication 사용하시면 좋을것 같습니다.

예)

ShareApi.shared.shareDefault(templatable: templatable) { [weak self] (sharingResult, error) in
  if let error = error {
    // ...
  } else {
    guard let sharingResult = sharingResult else { return }
    if UIApplication.shared.canOpenURL(sharingResult.url) {
      UIApplication.shared.open(sharingResult.url, options: [:], completionHandler: nil)
    }
  }
}

설명 감사합니다. 그런데 사실 저희가 카카오 앱을 호출하는 데 동일한 방법을 사용하고 있어서 좀 더 설명 드리자면:

  • 먼저, 시스템의 공유 기능을 사용하고 있는데, 전체 CustomShareViewController가 UIActivityViewController를 상속합니다.
  • 그런 다음 UIActivity를 상속하는 KakaoShareActivity를 사용자 정의했습니다.
  • 공유 뷰 컨트롤러는 다음과 같이 생성됩니다. shareVC = CustomShareViewController(activityItems: [item], applicationActivities: [KakaoShareActivity()]).

결국 저희는 CustomShareViewController 페이지에 두 개의 아이콘, 즉 커스텀 KakaoShareActivity의 아이콘과 카카오 앱에서 등록한 아이콘이 함께 표시되는 것을 원치 않는데,

제가 shareVC.excludedActivityTypes = [UIActivity.ActivityType(“com.iwilab.KakaoTalk.Share”)]를 사용하여 카카오 앱에서 등록한 액티비티를 제외하려고 했지만 작동하지 않았습니다.

카카오 앱에서 등록한 액티비티를 제외하는 다른 방법을 알고 계시는지 궁금합니다.

안녕하세요.

OS 공유는 iOS 종속적인 기능으로
excludedActivityTypes으로는 iOS가 미리 정의한 타입만 제외할 수 있기에 특정 앱을 제외할 수는 없을것으로 보입니다.

iOS가 제공하는 기능 내에서만 조치가 가능할 것으로 보이며
구현하신 KakaoShareActivity의 activityType에서 톡 액티비티를 반환하시면 제외 가능할 것으로 보입니다.
다만, 이는 어디까지나 iOS 종속적인 기능 내에서 구현으로 iOS가 반드시 동일하게 처리할 것이라고 보장해 드릴수는 없는점 참고 부탁드립니다.

추가로, 카카오디벨로퍼스에서는 운영정책 상, 카카오 상표의 식별력에 손상을 주지 않도록 명시 하고 있습니다.
따라서 KakaoShareActivity를 구현하실 경우 사용하실 아이콘은 톡의 아이콘과 동일한 것으로 사용 부탁드립니다.


ex)

override var activityType: UIActivity.ActivityType? {
  return UIActivity.ActivityType("com.iwilab.KakaoTalk.Share")
}

다른이야기지만,
톡 공유를 직접 사용하지 않고 공유 패널에서 제어하고자 하시는 이유가 있으실까요?
(ex, 쿼터 소진 시 일반 공유로 전환 등)

그렇군요, 이미 해당 코드를 사용하고 있어서 iOS 상에서 제외가 불가한 셋팅인가보네요…

override var activityType: UIActivity.ActivityType? {
return UIActivity.ActivityType(“com.iwilab.KakaoTalk.Share”)
}

그리고 톡 공유를 직접 사용하지 않고 공유 패널에서 제어하고자 하는거는 공유하기 버튼 눌렀을 때 다른 공유 방법(링크 공유, 인스타 공유 등)들도 있어야하고 쿼터 소진 시 일반 공유로 전환하기 위해서 함입니다.

이미 처리하고 계셨군요
직접 구현하여 테스트 해보았을 땐, 정상적으로 필터링된점 참고차 공유 드립니다
(iPhone 14, iOS 18.5)

class KakaoShareActivity: UIActivity {
    
    override var activityTitle: String? {
        return "카카오톡으로 공유"
    }
    
    override var activityImage: UIImage? {
        return UIImage(named: "kakao_icon")
    }
    
    override var activityType: UIActivity.ActivityType? {
        return UIActivity.ActivityType("com.iwilab.KakaoTalk.Share")
    }
    
    override class var activityCategory: UIActivity.Category {
        return .share
    }
...

감사합니다! 저희쪽에서도 iOS 업그레이드를 해서18.5, iphone 14 pro 로 해봤는데 안나오네요

  1. 혹시 카카오 공유 항목 하나를 제외해도 시스템 공유 항목(메일, 에어드랍, 복사 등)은 그대로 유지되나요?
  2. 카카오 앱 등록 항목(UIActivityItemProvider.placeholderItem이 (URL, String, Image)에 없는 항목)을 제외하는 방법은 알고 있지만, 동시에 시스템 공유 항목도 제외됩니다. 이 방법을 사용하고 계신가요?
  3. 혹시 사용하고 있지 않다면 어떤 식으로 재현하셨는지 좀 더 코드 공유가 가능하실까요?

안녕하세요.

테스트 시, UIActivityItemProvider는 구현하지 않고, 단지 UIActivity만 구현, applicationActivities만 사용하였습니다.
이 경우 시스템 공유 항목은 그대로 유지되었습니다.

안녕하세요,

말씀하신 부분으로 테스트를 다시 해봤는데 재현이 안돼서요. 데모를 썼는데 틀린 부분이 있는지 수정 해주실 수 있을까요?

저희는 궁국적으로 카톡 아이콘 1개 + 다른 아이템들도 보이는게 필요한데 - 마지막 이미지에서 보시다시피 상단의 경우 activityItem이 string인 경우 카카오 공유 아이템이 2개로 표기되고 다른 아이템(에어드랍, 메일, 메모 등)도 표기되는데 하단의 경우 activityItem 이 customer object인 경우 저희 커스텀 아이콘만 보이고 다른 아이템들은 다 안보이는 문제가 있습니다.



안녕하세요.

우선, 두번째 테스트 하신 방법이 잘 이해되지 않는데요

activityItems에 NSObject 하나만 전달하고 있는데,
일반적으로 다른 앱들은 이런 데이터에 대한 공유처리를 지원하지 않기에 모든걸 허용한 KakaoShareActivity만 표기됩니다.
구현하신 내용에 따른 정상 동작으로 보입니다.

이어서 첫번째의 경우 앞서 안내드린 바와 같이 카카오와 무관히 iOS 종속적인 이슈로 의도하신 동작 보장이 어렵다는점 참고 부탁드립니다.


아래 테스트 코드는 카카오에서 제공하는 데모 프로젝트 내에 구현하였습니다.

class KakaoShareActivity: UIActivity {
    
    override var activityTitle: String? {
        return "카카오톡으로 공유"
    }
    
    override var activityImage: UIImage? {
        return UIImage(named: "kakao_icon") // 앱 내 카카오 아이콘 사용
    }
    
    override var activityType: UIActivity.ActivityType? {
        return UIActivity.ActivityType("com.iwilab.KakaoTalk.Share")
    }
    
    override class var activityCategory: UIActivity.Category {
        return .share
    }
    
    override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
        return true
    }
    
    override func prepare(withActivityItems activityItems: [Any]) {
    }
    
    override func perform() {
        let feedTemplateJsonStringData =
          """
          {
              "object_type": "feed",
              "content": {
                  "title": "딸기 치즈 케익",
                  "description": "#케익 #딸기 #삼평동 #카페 #분위기 #소개팅",
                  "image_url": "http://mud-kage.kakao.co.kr/dn/Q2iNx/btqgeRgV54P/VLdBs9cvyn8BJXB3o7N8UK/kakaolink40_original.png",
                  "link": {
                      "mobile_web_url": "https://developers.kakao.com",
                      "web_url": "https://developers.kakao.com"
                  }
              },
              "item_content" : {
                    "profile_text" :"Kakao",
                    "profile_image_url" :"http://mud-kage.kakao.co.kr/dn/Q2iNx/btqgeRgV54P/VLdBs9cvyn8BJXB3o7N8UK/kakaolink40_original.png",
                    "title_image_url" : "http://mud-kage.kakao.co.kr/dn/Q2iNx/btqgeRgV54P/VLdBs9cvyn8BJXB3o7N8UK/kakaolink40_original.png",
                    "title_image_text" :"Cheese cake",
                    "title_image_category" : "cake",
                    "items" : [
                                    {
                                        "item" :"cake1",
                                        "item_op" : "1000원",
                                    },
                                    {
                                        "item" :"cake2",
                                        "item_op" : "2000원",
                                    },
                                    {
                                        "item" :"cake3",
                                        "item_op" : "3000원",
                                    },
                                    {
                                        "item" :"cake4",
                                        "item_op" : "4000원",
                                    },
                                    {
                                        "item" :"cake5",
                                        "item_op" : "5000원",
                                    }
                                ],
                                "sum" :"total",
                                "sum_op" : "15000원"
              },
              "social": {
                  "comment_count": 45,
                  "like_count": 286,
                  "shared_count": 845
              },
              "buttons": [
                  {
                      "title": "웹으로 보기",
                      "link": {
                          "mobile_web_url": "https://developers.kakao.com",
                          "web_url": "https://developers.kakao.com"
                      }
                  },
                  {
                      "title": "앱으로 보기",
                      "link": {
                          "android_execution_params": "key1=value1&key2=value2",
                          "ios_execution_params": "key1=value1&key2=value2"
                      }
                  }
              ]
          }
          """.data(using: .utf8)!
        
        //jsonObject
        if let feedTemplateJsonObject = SdkUtils.toJsonObject(feedTemplateJsonStringData) {
            ShareApi.shared.shareDefault(templateObject: feedTemplateJsonObject) { (sharingResult, error) in
                if let error = error {
                    self.activityDidFinish(false)
                }
                else {
                    guard let sharingResult = sharingResult else { return }
                    UIApplication.shared.open(sharingResult.url, options: [:], completionHandler: { success in
                        self.activityDidFinish(success)
                    })
                }
            }
        }
    }
}

...

let kakaoActivity = KakaoShareActivity()
let activityVC = UIActivityViewController(activityItems: ["any string"], applicationActivities: [kakaoActivity])
self.present(activityVC, animated: true)
...