[Flutter Error] Uncategorized (Xcode): Command CodeSign failed with a nonzero exit code 임시 해결 방법

문제 상황

Flutter에서 iOS 빌드 시 다음과 같은 에러가 발생하였다.

Launching lib/main.dart on iPhone 15 Pro in debug mode...
Running Xcode build...                                                  
Xcode build done.                                            6.2s
Failed to build iOS app
Uncategorized (Xcode): Command CodeSign failed with a nonzero exit code

Could not build the application for the simulator.
Error launching application on iPhone 15 Pro.
Uncategorized (Xcode): Command CodeSign failed with a nonzero exit code

까다로운 에러다. XCode에 관련된 에러는 주로 XCode를 업데이트했을 때, iOS 빌드 버전이 바뀌었을 때 등 상황에서 일어날 수 있다. 필자의 경우는 확실하지는 않지만 iCloud로 document를 백업하고, 연결을 끊으면서부터 문제가 발생하기 시작했다(연결을 끊을 경우 로컬의 document 폴더가 삭제되기 때문에 발생한 것으로 생각한다).

임시 해결 방법

우선 다음 사항들을 먼저 확인해보자.

일단 flutter doctor부터

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.16.7, on macOS 14.2.1 23C71
    darwin-arm64, locale ko-KR)
[✓] Android toolchain - develop for Android devices (Android SDK
    version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.1)
[✓] IntelliJ IDEA Ultimate Edition (version 2023.3.4)
[✓] VS Code (version 1.86.1)
[✓] Connected device (3 available)
[✓] Network resources

• No issues found!

우선 flutter doctor 부터 확인해보자. 여기서 문제가 발견되면 운이 좋은 것이다.

하지만 flutter doctor에서는 문제가 확인되지 않았다. 다음 과정으로 넘어간다.

codesign 확인

code sign에 관한 문제이므로 code sign의 위치도 확인해보자.

$ which codesign
/usr/bin/codesign

만약에 which codesign 을 통해서 얻은 path값이 없거나, 혹은 /usr/bin/codesign이 아니라면 문제가 있는 것이다. 가령 venv/anaconda/usr/bin/codesign 등 경로명이 다르면 문제가 생길 수 있다.

이 경우 export PATH=$PATH:/usr/bin/codesign을 통해서 해결할 수 있다.

하지만 나의 경우는 which codesign도 정상으로 나왔으니 다음으로 넘어간다.

XCode 로그인

XCode를 켠 후 cmd + ,을 눌러서 Configuration으로 들어가자.

Configuration → Accounts 탭에서 로그인이 제대로 되어 있는 지 확인해보자.

로그인이 안 되어 있다면 로그인을 해보고 다시 시도한다.

이마저 문제가 해결되지 않으므로 다음으로 넘어간다.

XCode에서 직접 실행 후 attach하기

XCode에서 Open Existing Project를 눌러 프로젝트를 연다.

우리가 열어야 할 것은 {project-name}/ios/Runner.xcodeproj 파일이다.

이런 화면이 뜬다. iOS 빌드 버전, Release, Debug, Profile 등의 Configuration 등을 설정할 수 있다.

여기서 설정을 변경하면 이는 실제 ios/Runner.xcworkspace/contents.xcworkspacedata 파일이나 ios/Runner.xcodeproj/project.pbxproj 파일 등 ios 폴더의 설정 파일에 반영이 된다.

여기서 iOS 버전을 가장 최신 버전(현재 기준 17.2 버전), 혹은 그보다는 살짝 아래 버전으로 낮춘 후, 좌측 상단 ▷ 버튼을 눌러서 xcode에서 직접 실행시킨다(iOS 시뮬레이터 켜주는 것을 잊지 말자).

이 과정에서도 빌드가 실패하는 잡음이 있었는데, 이는 이 글을 보고 해결하였다.

xcode를 통한 빌드는 성공하였다. 앱이 잘 실행되는 것을 확인.

맨 밑을 늘려보면, 로그를 확인할 수 있다.

flutter: The Dart VM service is listening on http://127.0.0.1:53713/9ySr_eAsCOs=/

이 부분이 중요하다. 여기서 포트 53713을 얻었다. 이 포트는 매번 바뀐다.

그리고서 vscode로 돌아와서 터미널에서 다음 명령어를 시도한다:

$ flutter attach --app-id "safetyedu.example.your_project" --device-vm-service-port 54585

하지만 나의 경우에는 위의 방법도 안 되었는데, --device-vm-service-port라는 명령어가 없다는 오류였다(Flutter 버전 업그레이드가 되면서 사라진 것 같다).

그래서 그냥 flutter attach --profile을 시도했다(혹은 flutter attach만을 시도해보라).

$ flutter attach --profile
Waiting for a connection from Flutter on iPhone 15 Pro...

Flutter run key commands.
h List all available interactive commands.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).
A Dart VM Service on iPhone 15 Pro is available at: http://127.0.0.1:54168/kA601h-CNFw=/
The Flutter DevTools debugger and profiler on iPhone 15 Pro is available at: http://127.0.0.1:9101?uri=http://127.0.0.1:54168/kA601h-CNFw=/

성공이다.

interactive 터미널이 켜지는데, 여기서 h를 누르면 모든 가능한 옵션키들을 확인할 수 있다.

하지만 내가 원하는 것은 이게 아니다.

vscode에서 cmd+shift+p로 명령 팔레트 창을 연 뒤, launch.json을 검색한다.

그러면 launch configuration을 할 수 있는 .vscode/launch.json이 뜬다.

{
    // IntelliSense를 사용하여 가능한 특성에 대해 알아보세요.
    // 기존 특성에 대한 설명을 보려면 가리킵니다.
    // 자세한 내용을 보려면 https://go.microsoft.com/fwlink/?linkid=830387을(를) 방문하세요.
    "version": "0.2.0",
    "configurations": [
        {
            "name": "safetyedu",
            "request": "launch",
            "type": "dart"
        },
        {
            "name": "safetyedu (profile mode)",
            "request": "launch",
            "type": "dart",
            "flutterMode": "profile"
        },
        {
            "name": "safetyedu (release mode)",
            "request": "launch",
            "type": "dart",
            "flutterMode": "release"
        },
        {
            "name": "safetyedu (attach)",
            "request": "attach",
            "type": "dart"
        } // 이 부분 추가
    ]
}

이름은 프로젝트 세팅마다 다를 것이다.

여기서 초기에는 맨 앞 세 세팅밖에 없을 것이다.

여기서 맨 마지막 부분을 추가한다.

{
    "name": "safetyedu (attach)",
    "request": "attach",
    "type": "dart"
}

그리고 다시 명령 팔레트 창으로 돌아와서, attach를 검색한다.

Debug: Attach to Flutter on Device가 보인다. 이를 누르면…

이렇게 되면 성공이다.

xcode에서 실행한 앱을 Attach하였다.

앱도 잘 작동하고, 터미널에서 로그도 정상적으로 출력된다.

임시 방편이기는 하나, 현재로써는 이 방법이 가장 유효한 진전이었다.

Detach는 우측에서 두 번째 빨간 플러그 아이콘을 누르면 되고, 나머지 아이콘은 전부 기존과 동일하게 사용할 수있다.

혹시 만약 아래와 같은 에러가 뜰 수 있다.

Waiting for a connection from Flutter on iPhone 15 Pro...
There are multiple Dart VM Services available.
Rerun this command with one of the following passed in as the app-id and device-vmservice-port:

  flutter attach --app-id "com.example.safetyedu" --device-vmservice-port 53713
  flutter attach --app-id "com.example.safetyedu (2)" --device-vmservice-port 54168

Exited (1).

글에서도 이미 터미널에서 flutter attach를 실행하였기에 같은 에러가 발생했다.

당황하지 말고, xcode에서 실행 중인 VM들을 전부 중지시킨다.

그리고 다시 하나만 실행시킨 후, 명령 팔레트에서 attach를 시도하면 된다.

Attach를 통해서 임시적으로 해결하기는 하였으나, 여전히 vscode에서 직접 실행하는 수단을 잃어버렸다.

추후 해결이 된다면 어떻게 해결하였는지, 이 글에 추가해서 공유하겠다.