Xcode 6 iOS Creating a Cocoa Touch Framework - Architectures issues

后端 未结 10 1811
眼角桃花
眼角桃花 2020-11-27 09:54

I\'m trying to make a dynamic framework for an iOS app. Thanks to the new version of Xcode (6) we can select a Cocoa Touch Framework when we create a new project and there i

相关标签:
10条回答
  • 2020-11-27 10:17

    Finally, I got it to work for me! And sorry for the big yellow frame, I have no idea how to format it better.

    The solution came from Claudio Romandi but the script linked has a minor problem in it. I can't comment on his post for I need 50 reputation so I'm left with little choice but to copy his post to have a full solution..

    1. Create an new (Aggregate) Target in your Framework Project
    2. Select the Aggregate in the Workspace and add a "New Run Script Phase"
    3. Put the Following Code in it:

      #!/bin/sh
      
      UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
      
      # make sure the output directory exists mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
      
      # Step 1. Build Device and Simulator versions xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION}
      -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
      
      # Step 2. Copy the framework structure (from iphoneos build) to the universal folder cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
      
      # Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
      
      # Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory lipo -create
      -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
      
      # Step 5. Convenience step to copy the framework to the project's directory cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
      
      # Step 6. Convenience step to open the project's directory in Finder open "${PROJECT_DIR}"
      
    4. Select the Aggregate in the Scheme Selection Drop Down

    5. Build, you're done!

    The problem was that the simulator directory was pointing to a non existant directory, changing "Framework" to "${PROJECT_NAME}" in 2 places did the trick :)

    0 讨论(0)
  • 2020-11-27 10:24

    This question was posted awhile ago(Xcode 6) but I encountered the same problem recently with Xcode 10.

    So the problem is: the built framework doesn't support enough architectures.

    In case one doesn't know what architectures stand for, different iPhone devices have different architectures, here's a complete list:

    • arm6: iPhone 1, 2, 3G
    • arm7: Used in the oldest iOS 7-supporting devices[32 bit]. iPhone 4, 4s
    • arm7s: As used in iPhone 5 and 5C[32 bit]. iPhone 5, 5c
    • arm64: For the 64-bit ARM processor in iPhone 5S[64 bit]. iPhone 5s and above.
    • arm64e: used on the A12 chipset. iPhone XS/XS Max/XR
    • i386: For the 32-bit simulator
    • x86_64: Used in 64-bit simulator

    So, if you are using the framework on simulator, the framework needs to support either i386 or x86_64; if you are running your app on iPhone 6, the framework needs to support arm64 architecture.

    Therefore, in most cases, a framework needs to support all the aforementioned architectures.

    Now back to how to solve the problem. We need to build the framework for both devices and simulators.

    How to build for devices:

    1. In "General", specify "Deployment Target".
    2. In "Build Settings", turn "Build Active Architectures Only" to "No"
    3. In "Build Settings", make sure "Valid Architectures" lists all the architectures you need. Usually we just use the defaults options(arm64, arm64e, armv7, armv7s).
    4. Go to "Edit Scheme" -> "Run" -> "Build Configuration", change "Build Configuration" to "Release"
    5. Select active Scheme "Generic iOS Device". Hit Cmd+B to build the project.
    6. Right click on [MyFrameworkProject].framework under "Products" folder in your Xcode project, and hit "Show in Finder".[MyFrameworkProject].framework supports all the architectures specified in step 2.
    7. Drag [MyFrameworkProject].framework to the project that needs to use this framework. Additionally, drag [MyFrameworkProject].framework to "Embedded Binaries" as well.

    How to build for simulators:

    1. Step 1 to 4 same as above.
    2. Select any simulator as active Scheme . Hit Cmd+B to build the project.
    3. Step 6 to 7 same as above.

    How to build for both devices and simulators:

    After you have the framework for devices, you will need to combine the framework for simulators and the framework for devices together with "lipo" command. Rename the framework for simulators to [MyFrameworkProject]_sim.framework and copy both frameworks to the same folder. Run command below in Terminal(make sure you are in the folder):

    lipo -create -output [MyFrameworkProject].framework/[MyFrameworkProject] [MyFrameworkProject].framework/MyFrameworkProject [MyFrameworkProject]_sim.framework/MyFrameworkProject
    

    Now [MyFrameworkProject].framework is the final product that supports both simulators and devices.

    0 讨论(0)
  • 2020-11-27 10:26

    An old video I did since the above link earlier is not available anymore.

    How to Create a Cocoa Touch Framework Using Xcode 6

    0 讨论(0)
  • 2020-11-27 10:27

    Based on all the responses, the post on raywenderlich.com and the gist created by Chris Conway I came up with this.

    Executing the following steps I was able to build a Cocoa Touch framework (including Swift and Objective-C files) that contains all architectures for both simulator and device:

    1. Create a new (Aggregate) target in your framework's project
    2. Under "Build Phases" select "Add Run Script" and copy the contents of this file
    3. Select the Aggregate target in the Scheme Selection drop down
    4. Build the target for the aggregate scheme

    Hope it helps :)

    UPDATE: Fixed an error in the gist where the paths in step #3 were incorrect. Thanks to Tokuriku!!

    UPDATE In Xcode 7 and 8, click File>New>Target... and there select "Other" group to select Aggregate target

    0 讨论(0)
提交回复
热议问题