Error building custom iOS Framework in Xcode - ios

This is the first time I have ever tried to create a custom iOS Framework. I'm trying to create custom iOS Framework using xCode by following this tutorial. I have gotten all the way to the very last step (Step 12).
Step 12: Build Project with Aggregate scheme
Select Aggregate("UniversaliOS") Scheme
Select iOS device
Build Project (⌘-B)
But the build fails with a Shell Script Invocation Error: Command /bin/sh failed with exit code 1. The error details are:
ditto: can't get real path for source
lipo: can't create temporary output file: /Users/pdl/Library/Developer/Xcode/DerivedData/InnerID-iOS-SDK-dgyjuudeootshidhpzlejhbyqvco/Build/Products/InnerID-iOS-SDK-Bundle.framework/InnerID-iOS-SDK-Bundle.lipo (No such file or directory)
Command /bin/sh failed with exit code 1
I have absolutely no clue as to what to do now. Any suggestions? I can provide the PhaseScriptExecution dump if necessary.
Thank you in advance for your help.

This is the correct shell script to be used (for swift).
CONFIG=Release
# Step 1. Make sure the output directory exists
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIG}-universal
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 2. Build Device and Simulator versions
codebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIG} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIG} -sdk iphonesimulator -arch x86_64 -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 3. Copy the framework structure to the universal folder. Subsequently copy the files of the swiftmodule (in Modules directory) of -iphonesimulator to the swiftmodule of universal framework directory.
cp -R "${BUILD_DIR}/${CONFIG}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
cp -R "${BUILD_DIR}/${CONFIG}-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}/${CONFIG}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIG}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
If you still have any doubts, you can look at the video tutorial.

You didn't compile your iOSBundle for both(Step 10) and directly attempt to merge both iOS simulator and device(Step 12).
Basically what Step 10 is doing?
Its's just creating Framework for both Simulator and Device, So for some reason your build folder gets empty and your script not able find framework for iOS-Simulator and Device both or any one.
Quick resolution :
Perform Step 10, one more time before Step 12, this will create iOS-simulator Framework and Device Framework both, After that build project for your Aggregate scheme, this will merge both framework.
You can find all three(iOS-Simulaor, Device, Merged) framework at below
/Users/jaym/Library/Developer/Xcode/DerivedData/iOSFramework-doeqysadgntrrlguuvcivuhapnlr/Build/Products/
In your case, /Users/pdl/Library/Developer/Xcode/DerivedData/InnerID-iOS-SDK-dgyjuudeootshidhpzlejhbyqvco/Build/Products/

Related

Undefined symbols for architecture x86_64 using Swagger API:

I am having this error in my Xcode project....So basically what I am doing is creating a static library that uses a Swagger Api that I have installed using CocoaPods. I am able to import the header files and use the header files in the library, but when I put the static library in another Xcode project I receive this error where It says _OBJC_CLASS_$_SWG....", referenced from: objc-class-ref in Sendable.o.... which is basically the class where I am using the Swagger header files.....
Things I have attempted:
1: Delete Derived Data folder, cleaned and rebuilt
2: made sure POD, library, and project using library have the same architectures as well as
3: made sure architecture build active is set to NO for all
4: made sure $(inherited) is in both library and project using library
5: installed pod file again in library
Things I noticed:
1: the library itself does not have POD in the header search path
2: I get the following warnings but ignored them
3: using Pod update gives me error saying GitHub is offline make sure you have internet connection, only removing and installing seem to work successfully.
My guess is that you are building the library for a single architecture - you are building it either for a Generic iOS Device, or some speciffic iOS device. Either way, you will not be able to use the library on a simulator (x86_64 architecture). Vice versa, if you build the library for a simulator, you will not be able to use it on a device.
If you want to use the same build on both devices and simulator, you need to create an universal library using a tool called lipo, either manually or by Build Phase script. Check out this article. Short summary:
Add an Aggregate target to your library project
Add a Run Script Build Phase
Paste this script into it:
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# 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}"
xcodebuild -target ${PROJECT_NAME} -configuration ${CONFIGURATION} -sdk iphonesimulator -arch x86_64 -arch i386 -arch armv7 -arch armv7s -arch arm64 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a"
echo "Universal library can be found here:"
echo ${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"
Build your Aggregate target and an universal library will be built

ERROR While Creating Archive : bitcode bundle could not be generated because 'Library Path(filename.o)' was built without full bit code?

I have created library for my Apple watch based on the Ray Wenderlich Tutorial. Steps I fallowed in brief.
Step 1 : I chosen template as Xcode -> File -> New -> watchOS -> Framework & Library -> Watch Static Library
Step 2 : Added files which are needed to make as library.
step 3 : Added header files in the library build in to public files.
step 4 : Run the application
step 5 : I want to create a universal library so I added target as Xcode -> File -> New -> Target -> Other -> Aggregate
step 6 : Added run script for simulator and watch os as
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
xcodebuild -target RBWatchModelManager ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator -arch x86_64 -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
UNIVERSAL_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-universal
mkdir -p "${UNIVERSAL_BUILD_DIR}"
# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-watchos/lib${PROJECT_NAME}.a"
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/include" "${UNIVERSAL_OUTPUTFOLDER}/"
and I tried one more script but tried either one of these two available scripts
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# Step 1. Build Device and Simulator versions
xcodebuild -target RBIWatchModelManager ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target RBIWatchModelManager -configuration ${CONFIGURATION} -sdk iphonesimulator -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target RBIWatchModelManager ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk watchos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-watchos/lib${PROJECT_NAME}.a"
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"
Using any one of this script i Created Library successfully.
Step 7 : I added this library (Universal folder library and header files (include folder)) to my actual project.
step 8 : selected library in the build phases Link Binary with Libraries
step 9 : Added Header search Path
Step 10 : Run the application. In simulator, and Device its running properly.
But While creating Archive of this project, I'm getting one error as shown in the image below.
Then I searched about this error, I tried the suggestion :
Suggestion I tried :
Changing the bit code. Because of I'm using watchOS there is no bit code option available in build settings while creating library So there is no scope for this solution.
Added -fembed-bitcode for Custom Compiler Flags in build setting of the Library while creating it. But no use. I'm getting the same error.
I thought this error because of particular file name showed in the error log. So I tried of separating those files and I created new library but then I'm getting same error for other files that are used for creating library. So no use..
I tried of enabling and disabling Enable Bitcode Option in Build settings of my original project where i have added this created library, no use at all.
At finally... Is there any other solution available to resolve this error. And One thing from apple i found is
For iOS apps, bitcode is the default, but optional. For watchOS and
tvOS apps, bitcode is required. If you provide bitcode, all apps and
frameworks in the app bundle (all targets in the project) need to
include bitcode.
After you distribute your app using iTunes Connect, you can download the dSYMs file for the build, described in Viewing and
Importing Crashes in the Devices Window.
Help me out ??

Need Clear concept of Framework

Attached code : http://speedy.sh/xTEp8/XYZFrameworkDemo.zip
I have create a framework name ABCFramework.framework having my Constant.h file where i put my MACRO used in my code.
For Ex:
#define WEBURL #"www.google.com/api"
Not i have following question.
1)
Please explain how do i distribute my ABCFramework.framework so it can be used in both simmulater and Iphone device,as till now i have to use both seperately with example code in which i want to use it.
2)
Please if a developer import my ABCFramework.framework in his code and he want to change the Constant.h WEBURL with his own WEBURL how to do it?
#define WEBURL #"www.google.com/api" //SDK URL
#define WEBURL #"www.yahoo.com/api" //USER URL TO BE ADD?
On adding aggregate target and run script
xcodebuild -target ABCFramework -sdk Debug-iphonesimulator
xcodebuild -target ABCFramework -sdk Debug-iphoneos
rm -rf "$SRCROOT/products" mkdir -p "$SRCROOT/products/ABCFramework"
lipo -create "$SOURCE_ROOT/build/Release-iphonesimulator/ABCFramework" "$SOURCE_ROOT/build/Release-iphoneos/ABCFramework" -o "$SOURCE_ROOT/products/ABCFramework/ABCFramework"
cp -r "$SOURCE_ROOT/build/Release-iphoneos/include/ABCFramework" "$SOURCE_ROOT/products/ABCFramework/include"
I am getting this error /
xcodebuild: error: SDK "Debug-iphonesimulator" cannot be located.
xcodebuild: error: SDK "Debug-iphoneos" cannot be located.
fatal error: lipo: can't open input file: /Users/xxxxxxxx/build/Release-iphonesimulator/ABCFramework (No such file or directory)
cp: /Users/xxxxxxxx/build//build/Release-iphoneos/include/ABCFramework: No such file or directory
NOTE: My project in which i create ABCFramework is XYZFrameworkDemo
1) To create a Universal framework that works on Simulator and device you have to build them separately and then use the lipo command to merge them. You do this by creating a Aggregate target and building the code once in simulator and once for device. You add a Run script phase to the aggregate target to build both simulator and device version which will go into their respective folders and then merge them using lipo command.
xcodebuild -target ABCFramework -sdk iphonesimulator
xcodebuild -target ABCFramework -sdk iphoneos
rm -rf "$SRCROOT/products"
mkdir -p "$SRCROOT/products/ABCFramework"
lipo -create "$SOURCE_ROOT/build/Release-iphonesimulator/ABCFramework" "$SOURCE_ROOT/build/Release-iphoneos/ABCFramework" -o "$SOURCE_ROOT/products/ABCFramework/ABCFramework"
cp -r "$SOURCE_ROOT/build/Release-iphoneos/include/ABCFramework" "$SOURCE_ROOT/products/ABCFramework/include"
2) You cannot change the macros in the framework after its built. You have to provide a api or a exported variable to set this property from the app that's integrating your framework.

iOS: How to create an independent framework

I am creating a little SDK, I want to release a Foo.framework.
What I have done is the following:
1- Create a project framework.
2- Add my code.
3- Add an agregator.
In the Agregator Build Phases I added the this run script
#!/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. 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 4. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
//Step 5. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"
Then I build the Agregator and get the Foo.framwork
My problem is, to be able to use the framework in another application I should:
step 1 - drag and drop the framework to my project.
step 2- And add it to the embedded binaries.
If I don't do the step 2 I get this error
dyld: Library not loaded: #rpath/Foo.framework/Foo
Referenced from: /private/var/mobile/Containers/Bundle/Application/00A2E4FD-23F4-43E8-AA85-505785A4FF16/foo.app/foo
Reason: image not found
How should I do if I want to use the framework only by dragging it to my project
(In other words add it only to Link Binary with Library) to make it simple to integrate.
Thanks in advance.
For All People facing this kind of issue the solution is here.
Just follow those instruction to build a Framework
https://github.com/jverkoey/iOS-Framework#walkthrough

Apple Mach-O Linker Warning. lib/libxyz.a missing required architecture i386 in file lib/libxyz.a

i am new to Apple iOS development. I am trying to create static library and add it to Main application.
Created Library Project and added it as a dependency project to the Main application. It works.
Now I took the lib.a (static library) from the Library project (present under debug-iphoneos) and copied to Main application. Tested the Main application - it works.
Now when i tried to copy the Main application to some other location (or even change the folder name - in which Main application is present) and try to run on Simulator, then i get following error:
ignoring file /Users/.../lib.a, missing required architecture i386 in file /Users/.../lib.a
I don't really understand the relation/dependency on the path.
the problem is solved.
I am using XCode 5.0.2 and iOS 7. when ever i compile the static library, the Xcode says it is building a universal library (but it is actually not). The 'Products' directory shows libxyz.a (which is in iphoneos/ directory) - this is actually for ARM6 & ARM7 for iPhone device. So when i took this 'libxyz.a' file and used it in another projects the linker used to throw a warning ' missing required architecture i386 '.
i have followed http://www.raywenderlich.com/41377/creating-a-static-library-in-ios-tutorial
used the script to generate single binary which contains both simulator & iphone device binary.
# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# Step 1. Build Device and Simulator versions
xcodebuild -target ImageFilters ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target ImageFilters -configuration ${CONFIGURATION} -sdk iphonesimulator -arch i386 BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a"
# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"

Resources