호댕의 iOS 개발

[iOS] 위젯 도입기 - 진짜 도입만 해보려했는데 처음부터 막혔다...!? 본문

Software Engineering/iOS

[iOS] 위젯 도입기 - 진짜 도입만 해보려했는데 처음부터 막혔다...!?

호르댕댕댕 2023. 7. 26. 22:30

회사에서 이번에 위젯 도입을 고려하고 계셔서 호기롭게 해보고 싶다는 생각이 들었다. 

 

아니 회사 프로젝트에서 SwiftUI도 사용해볼 수 있고 잠깐 찍먹만 해봤던 위젯을 개발해보면 너무 재밌을 것 같았기 때문이다. 

(지금도 위젯 재밌긴 하다... 하지만 지금 만난 문제는 재미없고 당황스러움밖에 없었다... ㅋ)

 

위젯에 대한 간단한 도입 방법과 설명은 요 글에서 이미 작성해놨다! 
(첨에는 기억이 안났는데 읽다보니 새록새록... 역시 기록은 중요하다)

https://ho8487.tistory.com/61

 

[iOS] Widget 알아보기 (+ AppExtension)

iOS 14 이후부터 위젯 기능을 사용할 수 있게 되었다. (물론... 안드로이드에선 진작 있긴 했지만... ) 위 아이패드 화면에서 흰 색 테두리로 표시해놓은 부분이 위젯이다. 이를 통해 사용자에게 앱

ho8487.tistory.com


🚨 문제상황

일단 Target으로 Widget Extension을 추가하려고 했다. 

타겟은 간단하게 Xcode > File > New > Target을 눌러 Widget Extension을 추가해주면 된다. 

 

이렇게 하면 기본적으로 현재 날짜가 텍스트로 들어가는 위젯 관련 코드들이 알아서 추가된다. 

 

그렇게 추가를 한 후 실행을 해봤다! 

 

아니 근데... 분명 빌드는 성공했는데... 위젯이 추가가 되지 않았다

 

원래는 제대로 추가가 됐다면 위젯 갤러리에서 해당 위젯을 확인하고 추가가 가능해야 한다. 

Scheme을 추가한 Target(Widget Extension)으로 둔 뒤 실행하면 알아서 위젯도 추가되고 말이다. 

 

하지만 실행은 됐지만 아무 변화도 없었다. 

 

차라리 에러라도 내면 원인이라도 찾아볼 수 있을 텐데 아무 에러 Alert나 로그도 없이 위젯이 실행되질 않았다. 

그래서 Preview라도 실행해보자는 마음에 프리뷰를 봤지만...

 

== PREVIEW UPDATE ERROR:

    FailedToLaunchAppError: Failed to launch {Bundle Identifier}.Widget
    
    ==================================
    
    |  RemoteHumanReadableError: Failed to launch widget extension
    |  
    |  ==================================
    |  
    |  |  RemoteHumanReadableError
    |  |  
    |  |  NSError: Error Domain=CHSErrorDomain Code=1300 "(null)"

요런 로그만 볼 수 있었다. 

 

그래서 요걸 단서로 구글링 시작! 

 

 

나와 유사한 경우는 있었지만 대부분의 해결책이 맞지 않았다. 

그래서 나는 UIKit과 WidgetKit 간의 호환성이 문제가 있나 해서 이 부분에 집중을 했는데...

 

iOS 오픈 채팅방에 질문을 올려보니 UIKit과는 전혀 문제가 아니라고 말씀해주셨다..

실제로 다른 UIKit 프로젝트에 위젯을 추가해보니 잘 실행이 됐다. 

 

흠 그럼 도대체 원인이 뭘까 고민하며 

  • Deployment Target도 다시 맞춰보고 
  • 다시 Extension을 추가해보기도 하고 
  • 테스트 기기도 재실행해보고
  • 클린 빌드도 당연히 해보고
  • 현재 잘 실행되고 있는 프로젝트와 Build Setting도 비교해보고 

많은 방법을 사용해봤지만 문제는 해결되지 않았다... 

 

StackOverFlow / Apple 포럼에서 비슷한 질문은 거의 다 찾아본 것 같은데 여기서도 뾰족한 방법을 찾진 못했다. 

 

그렇게 다음 날이 되고... 오늘도 계속 원인을 찾아나섰다.

그러다 갑자기 어제 단순히 컴파일 에러가 발생했다는 이유로 포기했던 해결책이 문득 떠올랐다. 

 

그것은 바로... 

 

현재 프로젝트 Target > Build Phases > Embed Foundation Extensions에 있는 Copy only when installing 항목을 체크 해제하기! 

 

이렇게 하면 나오지 않던 Error Alert가 나오게 됐다!

그것은 바로... Parent Bundle Identifier와 실행하는 Bundle Identifier의 접두어가 다르다는 것이다...

 

그러고 보니 우리 프로젝트는 Bundle Identifier가 Debug와 Release를 나눠서 관리하고 있었다... 그런데 현재 추가된 Widget Extension은 Debug Bundle Identifier와 다른 형태였던 것이다... 

 

com.hojoon.yang.debug // 기존 프로젝트의 Debug Bundle ID 예시
com.hojoon.yang.Widget // 추가한 Widget Extension의 Bundle ID 예시

com.hojoon.yang.debug.Widget // 이렇게 적어야 잘 실행됨!!! 🚨

 

그렇게 Bundle Identifier를 맞춰주니 시뮬레이터에서 드디어 우리 앱의 위젯을 확인할 수 있었다!!!!!

 

Bundle Identifier가 달라서 문제가 생긴 것이었고 Bundle Identifier를 맞춰주니 문제가 해결된 것이다.

(혹시 유사한 문제를 겪고 계시면 Bundle Identifier를 확인해보세요)

 

아니 그런데 왜 실기기에선 아직도 실행이 안되는거야...

 

빌드는 잘 됐지만 요런 에러 Alert가 나왔다. 

SendProcessControlEvent:toPid: encountered an error: Error Domain=com.apple.dt.deviceprocesscontrolservice Code=8 "Failed to show Widget '{Widget Extension 번들 ID}'

에휴.. 그래도 에러 로그라도 보여주는 것이 양반이다. 

 

이것도 구글링을 해봤지만 마땅한 해결방안은 찾지 못했다.

그러다 Deployement Target을 새롭게 Extension을 추가하면서 맞추지 못했던 것을 깨달았다...! 

 

이렇게 Deployment Target까지 프로젝트에 맞춰주니 실 기기에서도 잘 실행이 됐다.

(그럼 왜 시뮬레이터에선 된거지... ㅋㅋㅋ)

 

결론

Widget Extension을 추가할 때에는 Bundle Identifier와 Deployment Target까지 신경써서 맞춰주자! 

아니면 삽질의 늪에...

Comments