Azure Mobile Services iOS Library fails to build with Release configuration - ios

When archiving my iOS app the Windows Azure Mobile Services library fails to build.
The App builds fine when using Debug configuration.
While running this script:
/bin/sh -c \"/Users/user/Library/Developer/Xcode/DerivedData/myapp-bxucrfbhixkrpqfwaaovtqqpsvyd/Build/Intermediates/ArchiveIntermediates/MyApp\ (testing)/IntermediateBuildFilesPath/WindowsAzureMobileServices.build/Release-iphoneos/WindowsAzureMobileServices.build/Script-E8E37A27161FAA9600C13F00.sh\"
This turns out to be, this script form the "Build Phases" tab:
# Exit immediately on any errors
set -e
# Set some variables
OUTPUT=${BUILT_PRODUCTS_DIR}
WAMS="WindowsAzureMobileServices"
WAMS_FRAMEWORK="${WAMS}.framework"
WAMS_LIB="lib${WAMS}.a"
HEADERS="Headers"
# Create the needed directories for the framework
mkdir -p "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A"
mkdir -p "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
# Add the headers and lib to the framework
cp -a "${OUTPUT}/${HEADERS}/" "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
lipo -create "${OUTPUT}/${WAMS_LIB}" -output "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/${WAMS}"
# Set up the links to complete the framework
ln -sf Versions/Current/Headers "${OUTPUT}/${WAMS_FRAMEWORK}/Headers"
ln -sf "Versions/Current/${WAMS}" "${OUTPUT}/${WAMS_FRAMEWORK}/${WAMS}"
ln -sf A "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/Current"
It fails with this error:
cp:
/Users/user/Library/Developer/Xcode/DerivedData/MyApp-bxucrfbhixkrpqfwaaovtqqpsvyd/Build/Intermediates/ArchiveIntermediates/MyApp
(testing)/BuildProductsPath/Release-iphoneos/Headers/: No such file or
directory
I'm assuming that the error corresponds to this line:
cp -a "${OUTPUT}/${HEADERS}/" "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
I cannot see any differences in the build settings between Release and Debug.
Update
After some investigation I have determined that when Xcode archives a product it does not create the "headers" folder in ${BUILT_PRODUCTS_DIR}. It instead puts them in `/Build/Intermediates/ArchiveIntermediates/UninstalledProducts'. So the script fails.
Setting the "Skip Install" to NO for the Release build and then checking for the existence of the ${INSTALL_DIR} in the script will successfully build the library.
if [ -d "${INSTALL_DIR}" ]; then
cp -a "${INSTALL_DIR}/" "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
else
cp -a "${OUTPUT}/${HEADERS}/" "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
fi
However, Xcode failed to build because it can't find the headers:
fatal error: 'WindowsAzureMobileServices/WindowsAzureMobileServices.h' file not found
#import <WindowsAzureMobileServices/WindowsAzureMobileServices.h>
Update 2
Setting "Skip install" to no causes archiving issues, see this question: Compile, Build or Archive problems with Xcode 4 (and dependencies)
So I have removed the script that fails in the build phases and added "${PROJECT_DIR}/../azure-mobile-services/sdk/iOS/src" to the "User Header Search Paths" list.
This is messy and not my preferred solution.

Related

How to create FAT / Universal framework with XCode 13?

We were using a script to create a FAT framework before where we followed the below steps.
create a framework for iOS devices
create a framework for simulator devices
merge the above two frameworks & it will be your FAT / Universal framework.
The same script is not working fine after XCODE 12.4 so it seems that there is some change that is specific to XCODE 13+.
Can anyone please guide the steps to create FAT / Universal Framework with XCODE 13?
try this one "Build Phase" -> click "+" icon -> "New Run Script Phase" copy below code there and build with simulator and Any iOS Device.Your fat framework will be in your project folder
#1. After then make a fresh directory directory
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# 2. Copy Device(arm64) Framework at fresh universal folder location
cp -a "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
#3. Copy Sim(x86_64) Frameworks's "MyFramework.swiftmodule" Folder Content & paste it at Fat(x86_64 + arm64) Frameworks's "MyFramework.swiftmodule" folder.
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi
# 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. Copy output at Project Directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 6. Open Project Directory
open "${PROJECT_DIR}"#1. After then make a fresh directory directory
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# 2. Copy Device(arm64) Framework at fresh universal folder location
cp -a "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
#3. Copy Sim(x86_64) Frameworks's "MyFramework.swiftmodule" Folder Content & paste it at Fat(x86_64 + arm64) Frameworks's "MyFramework.swiftmodule" folder.
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi
# 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. Copy output at Project Directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 6. Open Project Directory
open "${PROJECT_DIR}"

How to access my app’s derived data folder itself?

I’m in the middle of moving my iOS app’s Firebase dependency from CocoaPods to Swift Package Manager.
Firebase’s Crashlytics requires a script to be executed while the app is building (using the Run Script build phase). Back in the CocoaPods days, I used to call the script the way documented by Google: "${PODS_ROOT}/FirebaseCrashlytics/run".
After I’ve switched to SPM, Firebase files are no longer in ${PODS_ROOT}, and there’s no such variable available at all. I know the file I need is now located in the DerivedData folder, specifically it’s at ~/Library/Developer/Xcode/DerivedData/MyApp-abcde/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run. The problem is, the MyApp-abcde folder is not easily referenced.
A Medium post I found suggested using the ${BUILD_DIR} build variable (in regard to the example above, it would resolve to <…>/MyApp-abcde/Build/Products), and calling the dirname command to move up the directory hierarchy.
This hack worked only for running the app. When I tried to archive it, ${BUILD_DIR} resolved to another path, namely <…>/MyApp-abcde/Build/Intermediates.noindex/ArchiveIntermediates/MyApp/BuildProductsPath. I tried a few more build variables, such as ${SYMROOT}, in place of ${BUILD_DIR}, but they also produce different paths depending on the operation.
So, here comes the question…
Is there a way to reliably reference my app’s derived data folder’s root (i.e. ~/Library/Developer/Xcode/DerivedData/MyApp-abcde) using Xcode’s build variables?
You were close. This should work:
${BUILD_DIR%Build/*}SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run
Crashlytics run script
To build&run from Xcode:
${BUILD_DIR%Build/*}SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run
To archive for distribution from Xcode Server at CI/CD:
${XCS_DERIVED_DATA_DIR%/*}/Dependencies/checkouts/firebase-ios-sdk/Crashlytics/run
To work for both at the same time:
if [[ "${XCS_DERIVED_DATA_DIR}" == "" ]]; then
${BUILD_DIR%Build/*}SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run
else
${XCS_DERIVED_DATA_DIR%/*}/Dependencies/checkouts/firebase-ios-sdk/Crashlytics/run
fi
I'm reworking my answer as I realized I haven't answered your question..
I have a run script that copies the build targets into a new folder. This works for both Build and Archive. Note that you need the -L on copy to follow the symlink
# Copy the built framework into a sibling to the project folder
if [[ "$CONFIGURATION" == "Debug" ]]; then
mkdir -p "$PROJECT_DIR/../../iwins-ios-sdk/debug"
rm -rf "$PROJECT_DIR/../../iwins-ios-sdk/debug/IWiNS_SDK.framework"
cp -LR "$BUILD_DIR/Debug-iphoneos/IWiNS_SDK.framework" "$PROJECT_DIR/../../iwins-ios-sdk/debug"
else
mkdir -p "$PROJECT_DIR/../../iwins-ios-sdk/release"
rm -rf "$PROJECT_DIR/../../iwins-ios-sdk/release/IWiNS_SDK.framework"
cp -LR "$BUILD_DIR/Release-iphoneos/IWiNS_SDK.framework" "$PROJECT_DIR/../../iwins-ios-sdk/release"
fi
Also, you can find all of the build envvars here:
https://gist.github.com/gdavis/6670468
So, it appears that $BUILD_DIR is different for build/release, but by copying the files to a known location at build time, you'll know where to find them.

xcodebuild where is the output binary?

Sorry, I'm very new to iOS development.
I'm building a Cordova/Meteor app. Meteor creates a build directory, and I'd like a command line script to build the binary to upload to itunesconnect.
Here's what I have so far:
#!/bin/bash
CODE_SIGN_IDENTITY="Michael"
NAME="appExpertAlerts"
# Create the xcode project
meteor add-platform ios
echo "STARTING BUILD"
meteor build ../../ops/production/ios \
--mobile-settings ../../ops/production/meteor/settings.json \
--server https://phone.app.io:443 \
--verbose
meteor remove-platform ios
popd
# Build the xcode project
pushd ios/ios/project
xcodebuild \
build \
-sdk iphoneos \
-configuration Release \
-xcconfig cordova/build.xcconfig \
-project "$NAME.xcodeproj" \
-target "$NAME" \
SHARED_PRECOMPS_DIR=$(pwd)/build/sharedpch \
CODE_SIGN_IDENTITY="$CODE_SIGN_IDENTITY" \
ARCHS="armv7 armv7s arm64" \
VALID_ARCHS="armv7 armv7s arm64" \
CONFIGURATION_BUILD_DIR=$(pwd)/build/device \
popd
The build says it's a success, and I can see output files, but I can't find the binary to upload to itunesconnect.
Where is the output binary? Or how do I create one?
I have not yet implemented an automation of the build-upload to itunesconnect, sounds interesting :-)
Yet, after the build has been triggered, I think, what you try to achieve would be better implemented as a "run script" build phase. There you have the variables set as described here:
https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW42
Especially interesting for you should be TARGET_BUILD_DIR:
TARGET_BUILD_DIR
Description: Directory path. Identifies the root of the directory
hierarchy that contains the product’s files (no intermediate build
files).
Run Script build phases that operate on product files of the
target that defines them should use the value of this build setting.
But Run Script build phases that operate on product files of other
targets should use BUILT_PRODUCTS_DIR instead.
Example values:
/Volumes/Users/genica/MyProject/build/Debug
/tmp/MyProject.dst/Users/genica/Applications
/Volumes/Users/genica/MyProject/build/UninstalledProducts Related to:
DEPLOYMENT_LOCATION (Deployment Location), INSTALL_PATH (Installation
Directory), SKIP_INSTALL.
The variables can be accessed as ${VAR NAME} in your script.
The .ipa archive can be created as shown in this SO article: Xcode "Build and Archive" from command line
You may pay special attention to the shenzen tool, which is, if I understand you correctly, exactly what you are currently building. https://github.com/nomad/shenzhen

Integrate Linphone in own iOS project

I am creating a voip call based project with Linphone and I have also successfully build and run the Linphone project and successfully run audio and video call. Now I am integrating Linphone in my own project and I am facing many problems and issues with this. I have used some following links for help but nowhere are complete instructions. Can anyone provide me the complete running steps for this-
http://shallwelearn.com/blog/build-linphone-for-iphone-and-ipad/
Integrate Linphone app to my iOS app
How to integrate Linphone into an existing project (SIP in IOS)
http://www.linphone.org/technical-corner/linphone/overview
How to integrate Linphone into an existing project (SIP in IOS)
http://lists.gnu.org/archive/html/linphone-developers/2014-09/msg00109.html
http://www.successmonkey.co.nz/blog/building-linphone-for-ios
Download Liblinphone iPhone SDK from the link: http://www.linphone.org/releases/ios choose latest one.
Move two folders (include and lib) to your project folder
Add paths to these folders in your project Build settings - INCLUDE folder goes to headers and LIB folder goes to libraries.
In General tab in Linked frameworks add all files from LIB folder
Download/clone the repo https://github.com/BelledonneCommunications/linphone-iphone
Find 4 files: LinphoneManager.h/.m and Utils.h/.m , include them in your project folder and add them to the left pane to other class files also
Try to compile your project - xCode will spam you with errors - this is ok.
You need to inspect errors and just delete all file imports causing errors (Some Linphone Address book files/ some config store files and some helpers classes that you do not need for basic use in your project (because most likely you already implemented this features in your existing project))
Then compile again and inspect all errors in methods. Comment delete any problematic chunks of code (there will be about 10-15 of them).
LinphoneManager class already include many useful features - like good watch and use of linphone core with good logging and etc and etc, but not all of them (unfortunately).
With Xcode 11 using macos 10.15.6 Catalina
Linphone SDK 4.4.0 Using Cocoapod
https://github.com/BelledonneCommunications/linphone-sdk/blob/master/README.md
Using a local linphone SDK
Clone the linphone-sdk repository from out gitlab:
$ git clone https://gitlab.linphone.org/BC/public/linphone-sdk.git --recursive
$ git submodule update --init --recursive
Or
$ git clone --recurse-submodules https://gitlab.linphone.org/BC/public/linphone-sdk.git
Rebuild the project:
PODFILE_PATH= pod install
where is your build directory of the linphone-sdk project, containing the linphone-sdk.podspec file and a linphone-sdk ouptut directory comprising built frameworks and resources.
Pod file looks like
source "https://gitlab.linphone.org/BC/public/podspec.git"
source "https://github.com/CocoaPods/Specs.git"
def common_pods
use_frameworks!
pod 'linphone-sdk', '4.4.0'
end
Then open linphone.xcworkspace with Xcode to build and run the app.
Linphone SDK 4.4.0 Using Compile
$ git clone https://gitlab.linphone.org/BC/public/linphone-sdk.git -- recursive
$ git submodule update --init --recursive
Or
$ git clone --recurse-submodules https://gitlab.linphone.org/BC/public/linphone-sdk.git
Goto the build directory
$ mkdir build && cd build
———————————
https://gitlab.linphone.org/BC/public/linphone-cmake-builder/blob/ios-3.13.19/README.python.md
first, install brew
$ brew install cmake
$ brew install yasm
$ brew install pkg-config
Install pip ->
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py
$ python -m pip install pystache //Check by $ python -m pip list
$ brew install doxygen
———————————
$ cmake .. -G Xcode -DLINPHONESDK_PLATFORM=IOS -DENABLE_G729=YES -DENABLE_G729B_CNG=YES -DENABLE_VCARD=OFF -DENABLE_ILBC=OFF -DENABLE_SILK=OFF -DENABLE_ISAC=OFF -DENABLE_MKV=OFF -DENABLE_GSM=OFF -DENABLE_DOC=OFF -DENABLE_UNIT_TESTS=OFF -DENABLE_LIME=OFF -DENABLE_GPL_THIRD_PARTIES=OFF -DENABLE_NON_FREE_CODECS=OFF
Note - in this step we will also enable G729 dedec support in our linphone sdk.
$ cmake --build . --config RelWithDebInfo
The compilation process is done now need to integrate with Xcode
Compiled Linphone SDK integrates into Xcode.
Find compiled sdk in below directory
linphone-sdk -> build -> linphone-sdk -> apple-darwin
Frameworks and share folder add into xcode project, Frameworks have multiple universal architectures.
Frameworks path add into framework search in build settings
Every framework of Frameworks folder, should be type "embed and sign" (means embed framework.) instead of "do not embed" as default while adding into Xcode Framework setting. it's the most very important part.
apple-darwin -> Tools folder have deply.sh script, copy its contents and create a new run script in "build settings" and paste in it"
the tricky part is where to place the 4th point's script for upload app using archive with strip and slice. Edit Scheme -> Archive -> open dropdown -> post actions -> + to add new script -> copy and paste.
6 (Optional). If experience script causes application crash due to fat library used our project, There is a minor change in the script, I found a solution from this URL - Errors building Xcode Project after adding in Run Script fatal error: lipo: input file
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
# Start of Script modify - identify if the framework is FAT. If it is, then it skips it.
if [ ! -f "${FRAMEWORK_EXECUTABLE_PATH}" ]; then
continue
fi
if xcrun lipo -info "${FRAMEWORK_EXECUTABLE_PATH}" | grep --silent "Non-fat"; then
echo "Framework non-fat, skipping: $FRAMEWORK_EXECUTABLE_NAME"
continue
fi
echo "Thinning framework $FRAMEWORK_EXECUTABLE_NAME"
# end of Script modify
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[#]}"
rm "${EXTRACTED_ARCHS[#]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
If you are using pod then de integrate pod using terminal command "pod deintegrate" on your pod directory. also delete .xcworkspace file from the project.
Now install pod using terminal command "pod install"
Note: If your case was Adding script causes app crash as I mentioned in 6th point but every time adding the script, have to pod de integrate help me avoid it.
:) Now enjoy using linphone sdk in your project.
end of linphone sdk
Linphone SDK Configuration in our projects.
Enable Codec - To enable audio codec first enable defaultValue of g729_preference in the Audio.plist file and last step In Project -> Target -> Build Settings find "Preprocessor macros" and include HAVE_G729, it prints in sip log like Adding G729/8000 for compatibility, just in case.
#Update - add 5th point fo compile for upload the app to the app store and G729 codec configuration.

Shell Script Invocation Error in Xcode 6

I used to compile universal static library with iOS-Universal-Framework, and works fine until I upgrade Xcdoe to 6.
I got the following error
** BUILD SUCCEEDED **
Create universal static library
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/libtool -static /Users/taofang/Library/Developer/Xcode/DerivedData/xxxxx/Build/Products/Debug-iphoneos/xxx.framework/xxx /Users/taofang/Library/Developer/Xcode/DerivedData/xxxxx/Build/Products/Debug-iphonesimulator/xxx.framework/xxx -o /Users/taofang/Library/Developer/Xcode/DerivedData/xxxxx/Build/Products/Debug-iphoneos/xxx.framework/xxx.temp
error: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/libtool: can't open file: /Users/taofang/Library/Developer/Xcode/DerivedData/xxxxx/Build/Products/Debug-iphonesimulator/xxx.framework/xxx (No such file or directory)
If i use Xcode 5 to do the job, it will be fine.
Beside, I selected Device as my compile target, but why the libtool tries to open a file under iphonesimulator folder?
That means there are no header files in any of your build folders. It may be because you haven't configured your library project to export any header files.
Go to your Project Target >> Build Phases >> + sign >> Add a new build phase
You need to add a Copy files Phase that copies the headers you want to the include folder.
Instead of chmod a+x [PATH], I could resolve it with chmod 777 [PATH].
You can use the following command to recursively own all the files and folders in the path like...
chmod -R 777 ./
For more details:
Chmod 777 to a folder and all contents

Resources