简体   繁体   中英

Turn Package.swift file into binary XCFramework

Someone in my company created a Swift package SDK and now I was tasked to publish it for the customer in a binary way so that the end customers that will use the SDK will not be able to see the source code of it. This is how the SDK is built: the SDK in xcode (ps the build folder is empty)

From my reading on the subject I understand that I need to export the files into an XCFramework file. However, the vast majority of guides I've encountered explain how to make this progress from a framework , and not from a package like in my case..

The only guide I found that seems exactly like what I need is this one, however I get an error right on the first relevant terminal command of xcodebuild -scheme [my scheme name] -sdk iphoneos -configuration Release ARCHS="arm64" BUILD_DIR="./Build" . This is the main error line I get: xcodebuild: error: Building a Swift package requires that a destination is provided using the "-destination" option. The "-showdestinations" option can be used to list the available destinations. xcodebuild: error: Building a Swift package requires that a destination is provided using the "-destination" option. The "-showdestinations" option can be used to list the available destinations. . Why would I need to specify a destination? I want the SDK to work for all the devices (ios 13+). Non of the forums I searched in online helped me solve this.

I also read Apple's instructions here but got very confused about how the terminal command in step 2 is supposed to look like in my case. Are some of the fields mandatory and some are not?

Any help would be much appreciated!!

Assuming you are working with iOS only and you need an xcframework for both device and simulator architectures, in order to generate an XCFramework from a swift package you need to:

  1. Mark your Package as .dynamic (ie .library(name: "Foo", type: .dynamic, targets: ["Foo"]) )
  2. Archive the project for both simulator and device. This will generate a .framework file for each architecture.
  3. Copy Modules folders (if any) into the .xcarchive files
  4. Copy the bundles (if any) into the .xcarchive files
  5. Create the xcframework with the frameworks created in step 2

Here's a bash script, based on the one from this swift forums post , to create an XCFramework from a swift package (in my case, I have my package inside an xcworkspace. I didn't try it as a standalone package, not sure if that can be done):

Change the input parameters as needed :), but most importantly replace <Your project name> and <your workspace> .

#!/bin/bash

PROJECT_NAME="<Your project name>"
PROJECT_DIR="./Packages/${PROJECT_NAME}" # Relative path to the directory containing the `Package.swift` file
BUILD_FOLDER="./build"
OUTPUT_DIR="${PROJECT_DIR}/Output"
SIMULATOR_ARCHIVE="${OUTPUT_DIR}/${PROJECT_NAME}-iphonesimulator.xcarchive"
DEVICE_ARCHIVE="${OUTPUT_DIR}/${PROJECT_NAME}-iphoneos.xcarchive"

rm -rf "$OUTPUT_DIR"
mkdir -p "$OUTPUT_DIR"

# 2 iterations: 1 for device arch and another for simulator arch
for PLATFORM in "iOS" "iOS Simulator"; do
    case $PLATFORM in
      "iOS")
        ARCHIVE=$DEVICE_ARCHIVE
        SDK=iphoneos
        RELEASE_FOLDER="Release-iphoneos"
      ;;
      "iOS Simulator")
        ARCHIVE=$SIMULATOR_ARCHIVE
        SDK=iphonesimulator
        RELEASE_FOLDER="Release-iphonesimulator"
      ;;
    esac

    # Step 2
    xcodebuild archive \
      -workspace <your workspace>.xcworkspace \
      -scheme $PROJECT_NAME \
      -destination="generic/platform=${PLATFORM}" \
      -archivePath $ARCHIVE \
      -sdk $SDK \
      -derivedDataPath $BUILD_FOLDER \
      SKIP_INSTALL=NO \
      BUILD_LIBRARY_FOR_DISTRIBUTION=YES

    FRAMEWORK_PATH="${ARCHIVE}/Products/Library/Frameworks/${PROJECT_NAME}.framework"
    MODULES_PATH="$FRAMEWORK_PATH/Modules"
    mkdir -p $MODULES_PATH

    BUILD_PRODUCTS_PATH="${BUILD_FOLDER}/Build/Intermediates.noindex/ArchiveIntermediates/${PROJECT_NAME}/BuildProductsPath"
    RELEASE_PATH="${BUILD_PRODUCTS_PATH}/${RELEASE_FOLDER}"
    SWIFT_MODULE_PATH="${RELEASE_PATH}/${PROJECT_NAME}.swiftmodule"
    RESOURCES_BUNDLE_PATH="${RELEASE_PATH}/${PROJECT_NAME}_${PROJECT_NAME}.bundle"

    # Step 3
    if [ -d $SWIFT_MODULE_PATH ] 
    then
      cp -r $SWIFT_MODULE_PATH $MODULES_PATH
    fi

    # Step 4
    if [ -e $RESOURCES_BUNDLE_PATH ] 
    then
      cp -r $RESOURCES_BUNDLE_PATH $FRAMEWORK_PATH
    fi

done

# Step 5
xcodebuild -create-xcframework \
 -framework "${DEVICE_ARCHIVE}/Products/Library/Frameworks/${PROJECT_NAME}.framework" \
 -framework "${SIMULATOR_ARCHIVE}/Products/Library/Frameworks/${PROJECT_NAME}.framework" \
 -output "${OUTPUT_DIR}/${PROJECT_NAME}.xcframework"

When the script ends, you will see 3 files in the output folder:

  • Device xcarchive
  • Simulator xcarchive
  • XCFramework

You can remove the xcarchives, as you won't need them anymore (you can also update the script to do that for you).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM