Wednesday, February 8, 2023
HomeiOS Developmentios - Bug fastlane & Capacitor: Transporter switch failed with Error Codes...

ios – Bug fastlane & Capacitor: Transporter switch failed with Error Codes ITMS-90713, ERROR ITMS-90022, ERROR ITMS-90023 and ITMS-90704


Subject Description

Each time I run upload_to_testflight with fastlane in a capacitor-powered app surroundings, I get the errors talked about within the title of this subject and listed beneath:

    ----------------------------------
    --- Step: upload_to_testflight ---
    ----------------------------------
    Creating authorization token for App Retailer Join API
    Able to add new construct to TestFlight (App: xxxxxx)...
    Going to add up to date app to App Retailer Join
    This would possibly take a couple of minutes. Please do not interrupt the script.
    Transporter switch failed.
    
    ERROR ITMS-90713: Lacking Data.plist worth. A price for the Data.plist key 'CFBundleIconName' is lacking within the bundle 'xxxx'. Apps constructed with iOS 11 or later SDK should provide app icons in an asset catalog and should additionally present a worth for this Data.plist key. For extra data see http://assist.apple.com/xcode/mac/present/#/dev10510b1f7.
    ERROR ITMS-90022: Lacking required icon file. The bundle doesn't comprise an app icon for iPhone / iPod Contact of precisely '120x120' pixels, in .png format for iOS variations >= 10.0. To help older variations of iOS, the icon could also be required within the bundle exterior of an asset catalog. Ensure the Data.plist file contains applicable entries referencing the file. See https://developer.apple.com/documentation/bundleresources/information_property_list/user_interface
    ERROR ITMS-90023: Lacking required icon file. The bundle doesn't comprise an app icon for iPad of precisely '167x167' pixels, in .png format for iOS variations supporting iPad Professional. To help older working techniques, the icon could also be required within the bundle exterior of an asset catalog. Ensure the Data.plist file contains applicable entries referencing the file. See https://developer.apple.com/documentation/bundleresources/information_property_list/user_interface
    ERROR ITMS-90023: Lacking required icon file. The bundle doesn't comprise an app icon for iPad of precisely '152x152' pixels, in .png format for iOS variations >= 10.0. To help older working techniques, the icon could also be required within the bundle exterior of an asset catalog. Ensure the Data.plist file contains applicable entries referencing the file. See https://developer.apple.com/documentation/bundleresources/information_property_list/user_interface
    ERROR ITMS-90704: Lacking App Icon. An app icon measuring 1024 by 1024 pixels in PNG format should be included within the Asset Catalog of apps constructed for iOS, iPadOS, or watchOS. With out this icon, apps can't be submitted for overview. For particulars, see https://developer.apple.com/ios/human-interface-guidelines/icons-and-images/app-icon/.

Tried and Failed makes an attempt

Xcode recordsdata

I double-checked the icons, and to me, they appear to be appropriate:

image

The recordsdata are additionally seen in XCode with none warning signal within the asset catalog part:

image

Goal Membership can be set appropriately to App.

The settings seen beneath appear to be legitimate as nicely:

image

Contents.json

{
  "pictures" : [
    {
      "size" : "20x20",
      "idiom": "iphone",
      "filename" : "icon-only-20@2x.png",
      "scale": "2x"
    },
    {
      "size" : "20x20",
      "idiom": "iphone",
      "filename" : "icon-only-20@3x.png",
      "scale": "3x"
    },
    {
      "size" : "20x20",
      "idiom": "ipad",
      "filename" : "icon-only-20.png",
      "scale": "1x"
    },
    {
      "size" : "20x20",
      "idiom": "ipad",
      "filename" : "icon-only-20@2x.png",
      "scale": "2x"
    },
    {
      "size" : "29x29",
      "idiom" : "iphone",
      "filename" : "icon-only-29@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "29x29",
      "idiom" : "iphone",
      "filename" : "icon-only-29@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "40x40",
      "idiom" : "iphone",
      "filename" : "icon-only-40@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "40x40",
      "idiom" : "iphone",
      "filename" : "icon-only-40@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "60x60",
      "idiom" : "iphone",
      "filename" : "icon-only-60@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "60x60",
      "idiom" : "iphone",
      "filename" : "icon-only-60@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "29x29",
      "idiom" : "ipad",
      "filename" : "icon-only-29.png",
      "scale" : "1x"
    },
    {
      "size" : "29x29",
      "idiom" : "ipad",
      "filename" : "icon-only-29@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "40x40",
      "idiom" : "ipad",
      "filename" : "icon-only-40.png",
      "scale" : "1x"
    },
    {
      "size" : "40x40",
      "idiom" : "ipad",
      "filename" : "icon-only-40@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "76x76",
      "idiom" : "ipad",
      "filename" : "icon-only-76.png",
      "scale" : "1x"
    },
    {
      "size" : "76x76",
      "idiom" : "ipad",
      "filename" : "icon-only-76@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "83.5x83.5",
      "idiom" : "ipad",
      "filename" : "icon-only-83.5@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "1024x1024",
      "idiom" : "ios-marketing",
      "filename" : "icon-only-1024.png",
      "scale" : "1x"
    }
  ],
  "data" : {
    "model" : 1,
    "writer" : "xcode"
  }
}

I’ve created them utilizing a third-party software, talked about right here: https://stackoverflow.com/a/45122603/1238150, known as “Icon Set Creator.”

Data.plist

My Data.plist seems to be like this:

image

    <?xml model="1.0" encoding="UTF-8" ?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
      "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist model="1.0">
    <dict>
        <key>CFBundleDevelopmentRegion</key>
        <string>de</string>
        <key>CFBundleDisplayName</key>
        <string>$(PRODUCT_BUNDLE_NAME)</string>
        <key>CFBundleExecutable</key>
        <string>$(EXECUTABLE_NAME)</string>
        <key>CFBundleIdentifier</key>
        <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleName</key>
        <string>$(PRODUCT_NAME)</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
        <string>$(MARKETING_VERSION)</string>
        <key>CFBundleIconName</key>
        <string>AppIcon</string>
        <key>CFBundleURLTypes</key>
        <array>
            <dict>
                <key>CFBundleTypeRole</key>
                <string>Editor</string>
                <key>CFBundleURLName</key>
                <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
                <key>CFBundleURLSchemes</key>
                <array>
                    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
                </array>
            </dict>
        </array>
        <key>CFBundleVersion</key>
        <string>$(CAPACITOR_PROJECT_VERSION)</string>
        <key>ITSAppUsesNonExemptEncryption</key>
        <false />
        <key>UILaunchStoryboardName</key>
        <string>LaunchScreen</string>
        <key>UIMainStoryboardFile</key>
        <string>Most important</string>
        <key>UIRequiredDeviceCapabilities</key>
        <array>
            <string>armv7</string>
        </array>
        <key>UIStatusBarStyle</key>
        <string>UIStatusBarStyleDarkContent</string>
        <key>UISupportedInterfaceOrientations</key>
        <array>
            <string>UIInterfaceOrientationPortrait</string>
        </array>
        <key>UISupportedInterfaceOrientations~ipad</key>
        <array>
            <string>UIInterfaceOrientationPortrait</string>
            <string>UIInterfaceOrientationPortraitUpsideDown</string>
            <string>UIInterfaceOrientationLandscapeLeft</string>
            <string>UIInterfaceOrientationLandscapeRight</string>
        </array>
        <key>UIUserInterfaceStyle</key>
        <string>Gentle</string>
        <key>UIViewControllerBasedStatusBarAppearance</key>
        <true />
    
        <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
        <string>Add your description for requiring permission right here</string>
    
        <key>NSLocationAlwaysUsageDescription</key>
        <string>Add your description for requiring permission right here</string>
    
        <key>NSLocationWhenInUseUsageDescription</key>
        <string>Add your description for requiring permission right here</string>
    </dict>
    </plist>

undertaking.pbxproj

This file incorporates references to the 4 schemes I’ve created growth, staging, beta and manufacturing. Every of them has a minimum of the next construct setting utilized:

    buildSettings = {
        ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
        ...
        INFOPLIST_FILE = App/Data.plist;
        ...
    }

Here is the total config of the staging surroundings used within the case I describe:

    F8AD9F41291D56E00xxxxxx /* Staging */ = {
                isa = XCBuildConfiguration;
                buildSettings = {
                    ALWAYS_SEARCH_USER_PATHS = NO;
                    ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
                    CLANG_ANALYZER_NONNULL = YES;
                    CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
                    CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
                    CLANG_CXX_LIBRARY = "libc++";
                    CLANG_ENABLE_MODULES = YES;
                    CLANG_ENABLE_OBJC_ARC = YES;
                    CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
                    CLANG_WARN_BOOL_CONVERSION = YES;
                    CLANG_WARN_COMMA = YES;
                    CLANG_WARN_CONSTANT_CONVERSION = YES;
                    CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                    CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
                    CLANG_WARN_EMPTY_BODY = YES;
                    CLANG_WARN_ENUM_CONVERSION = YES;
                    CLANG_WARN_INFINITE_RECURSION = YES;
                    CLANG_WARN_INT_CONVERSION = YES;
                    CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
                    CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
                    CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                    CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
                    CLANG_WARN_STRICT_PROTOTYPES = YES;
                    CLANG_WARN_SUSPICIOUS_MOVE = YES;
                    CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
                    CLANG_WARN_UNREACHABLE_CODE = YES;
                    CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                    CODE_SIGN_IDENTITY = "iPhone Developer";
                    COPY_PHASE_STRIP = NO;
                    DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                    ENABLE_NS_ASSERTIONS = NO;
                    ENABLE_STRICT_OBJC_MSGSEND = YES;
                    GCC_C_LANGUAGE_STANDARD = gnu11;
                    GCC_NO_COMMON_BLOCKS = YES;
                    GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                    GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                    GCC_WARN_UNDECLARED_SELECTOR = YES;
                    GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                    GCC_WARN_UNUSED_FUNCTION = YES;
                    GCC_WARN_UNUSED_VARIABLE = YES;
                    IPHONEOS_DEPLOYMENT_TARGET = 13.0;
                    MTL_ENABLE_DEBUG_INFO = NO;
                    SDKROOT = iphoneos;
                    SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
                    VALIDATE_PRODUCT = YES;
                };
                identify = Staging;
            };
            F8AD9F42291D56E000xxxxxx /* Staging */ = {
                isa = XCBuildConfiguration;
                baseConfigurationReference = 088FDA9807EE2E8C50xxxxxx /* Pods-App.staging.xcconfig */;
                buildSettings = {
                    ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
                    CLANG_ENABLE_MODULES = YES;
                    CODE_SIGN_IDENTITY = "iPhone Distribution";
                    CODE_SIGN_STYLE = Guide;
                    CURRENT_PROJECT_VERSION = "$(CAPACITOR_PROJECT_VERSION)";
                    DEVELOPMENT_TEAM = xxxxx;
                    INFOPLIST_FILE = App/Data.plist;
                    IPHONEOS_DEPLOYMENT_TARGET = 13.0;
                    "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.2;
                    LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
                    MARKETING_VERSION = "$(CAPACITOR_VERSION_NAME)";
                    PRODUCT_BUNDLE_IDENTIFIER = "${CAPACITOR_APP_ID}";
                    PRODUCT_BUNDLE_NAME = "${CAPACITOR_APP_NAME}";
                    PRODUCT_NAME = "$(TARGET_NAME)";
                    PROVISIONING_PROFILE_SPECIFIER = "match AppStore xx.xx.xx";
                    "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "";
                    SUPPORTS_MACCATALYST = YES;
                    SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
                    SWIFT_VERSION = 5.0;
                    TARGETED_DEVICE_FAMILY = "1,2";
                };
                identify = Staging;
            };

App.ipa

I even investigated the generated app file and its package deal content material, and the Data.plist contained CFBundleIconName once I added it however it made no distinction.

The App.ipa I’m referring to was created with fastlane‘s build_ios_app (aka health club) motion, not with XCodes GUI.

Surroundings

fastlane surroundings

### Stack

| Key                         | Worth                                       |
| --------------------------- | ------------------------------------------- |
| OS                          | 12.4                                        |
| Ruby                        | 3.1.2                                       |
| Bundler?                    | false                                       |
| Git                         | git model 2.38.0                          |
| Set up Supply         | ~/.asdf/installs/ruby/3.1.2/bin/fastlane    |
| Host                        | macOS 12.4 (21F79)                          |
| Ruby Lib Dir                | ~/.asdf/installs/ruby/3.1.2/lib             |
| OpenSSL Model             | OpenSSL 3.0.5 5 Jul 2022                    |
| Is contained                | false                                       |
| Is homebrew                 | false                                       |
| Is put in through Material.app | false                                       |
| Xcode Path                  | /Purposes/Xcode.app/Contents/Developer/ |
| Xcode Model               | 13.4.1 
| Swift Model               | 5.6.1                                       |

That is the content material of my Fastfile

    # Impressed by
    # - https://capgo.app/weblog/automatic-capacitor-ios-build-github-action/
    
    default_platform(:ios)
    
    config = JSON.parse(File.learn('../App/capacitor.config.json'))
    
    keychain_name="fastlane-certificates"
    keychain_password = 'xxx'
    
    def delete_temp_keychain(identify)
      # https://docs.fastlane.instruments/actions/delete_keychain
      delete_keychain(identify:) if File.exist? File.expand_path("~/Library/Keychains/#{identify}-db")
    finish
    
    def create_temp_keychain(identify, password)
      # https://docs.fastlane.instruments/actions/create_keychain/
      create_keychain(
        identify:,
        password:,
        unlock: false,
        timeout: 0
      )
    finish
    
    def ensure_temp_keychain(identify, password)
      delete_temp_keychain(identify)
      create_temp_keychain(identify, password)
    finish
    
    platform :ios do
      before_all do |_lane, _options|
        setup_ci if ENV['CI']
      finish
    
      after_all do |_lane, _options|
        delete_temp_keychain(keychain_name)
      finish
    
      error do |_lane, _exception, _options|
        delete_temp_keychain(keychain_name)
      finish
    
      private_lane :buildNextApp do |choices|
        UI.message('Construct App...')
        yarn(
          command: "construct:internet:#{choices[:target]}",
          package_path: "#{Dir.pwd}/../../../package deal.json"
        )
        UI.message('Constructed App')
      finish
    
      private_lane :getApiKey do
        app_store_connect_api_key(
          key_id: 'xx',
          issuer_id: 'xx',
          key_filepath: "#{Dir.pwd}/xx.p8",
          period: 1200, # non-compulsory (most 1200)
          in_house: false # non-compulsory however could also be required if utilizing match/sigh
        )
      finish
    
      lane :stagingBuild do
        buildNextApp(goal: 'staging')
      finish
    
      desc 'Push a brand new staging construct to TestFlight'
      lane :staging do
        stagingBuild
    
        ensure_temp_keychain(keychain_name, keychain_password)
    
        match(
          sort: 'appstore',
          app_identifier: [config['appId']],
          api_key: getApiKey,
          readonly: false,
          fail_on_name_taken: true,
          keychain_name:,
          keychain_password:
        )
    
        # (https://docs.fastlane.instruments/actions/build_ios_app/)
        build_ios_app(
          clear: true,
          configuration: 'Staging',
          export_method: 'app-store',
          scheme: 'staging',
          silent: true,
          workspace: 'App.xcworkspace'
        )
    
        upload_to_testflight(
          app_identifier: config['appId'],
          ipa: "#{Dir.pwd}/../App.ipa",
          skip_waiting_for_build_processing: true,
          expire_previous_builds: true,
          skip_submission: true,
          submit_beta_review: false,
          distribute_external: false,
          notify_external_testers: false
        )
    
      finish
    finish

And the one from my AppFile

    require 'json'
    
    config = JSON.parse(File.learn('../App/capacitor.config.json'))
    
    app_identifier(config['appId'])
    # apple_id("[[APPLE_ID]]") # Your Apple Developer Portal username
    itc_team_id('xxx') # App Retailer Join Workforce ID (https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/person/element)
    team_id('xxx') # Developer Portal Workforce ID (https://developer.apple.com/account/#MembershipDetailsCard)

I spent hours now and don’t have any clue what’s improper… I’m about to strive setting

    ENV['ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD'] = 'true'

as talked about in a number of non-related points reported by others within the fastlane GitHub repository:


For those who learn this far – thanks! I hope you learn this far since you both have an answer or you’re in the identical boat as I’m and hope we are able to discover a answer collectively! šŸ˜€

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments