Distribute Swift App In-house - ios

I have 2 applications one in Objective-C and one in swift using Xcode 6.
Both are different application which has different aspect.
I try to distribute both apps in-house using Enterprise Certificate and Profile via Cisco Meraki.
Objective-C app successfully distribute, but Swift fails.
Even though my iPad can successfully download swift app from meraki but once it finishes installing it shows "Unable to Download App" - App Name could not be installed at this time.
So does Apple prevent us from distribute swift app even for in-house?
Thanks a lot.

The answer is that we can get around it. This helped me out, build the Swift app, use following command to archive (replace capital names with your variables):
xcrun -sdk iphoneos PackageApplication -v "APP_NAME.app" \
-o "PATH/APP_NAME.ipa" \
--sign "SIGNING_IDENTITY" \
--embed "PROVISIONING_PROFILE"

Related

The code signature version is no longer supported

An app signed with a codesign version provided on an older macOS, like Catalina (10.15) will not run on iOS 15 because the lastest version you can install is Xcode 12.4.
Xcode 12.5 seems to change the behavior of codesigning. When installing you get the error message:
The code signature version is no longer supported
Is there a workaround?
Notice
This answer is mostly for people using older versions of Xcode. My build farm was for a time stuck at Xcode 12.4 because some Mac minis couldn't be upgraded past Catalina. If you are using a recent Xcode 13+ this is not your issue. Probably cruft of some kind in your project.
If you're still using an Xcode 12 release it is time to let go. The only reason to use 12.4 would be because you're stuck on Catalina and new problems are cropping up that will not be worked around so easily.
codesign --generate-entitlement-der
Apple has changed the codesign signature to include DER encoded entitlements in addition to the plist encoded entitlements. This additional DER encoded entitlements section is required in iOS 15 and becomes the default behavior of codesign in the latest Xcode. To use codesign on an older machines with an older version of Xcode add the --generate-entitlement-der flag to your call to codesign.
If signing through Xcode, you can add this flag to the OTHER_CODE_SIGN_FLAGS setting in the Build Settings tab.
If codesigning at the command-line:
CODESIGN_ALLOCATE=$( xcrun --find codesign_allocate ); export CODESIGN_ALLOCATE
xcrun codesign --generate-entitlement-der ...
The source of this information was the Apple Forum thread and the answer from Matt Eaton in DTS at Apple.
In the Xcode 12.5 Release Notes there is also a reference to the new signature format. However, it seems the information is not entirely correct.
General advice
If you have a non-trivial setup like CocoaPods, you should probably de-integrate and re-integrate and of course do a project clean. These sorts of 'me too' answers really just add noise to the signal and anyone doing this sort of development should have already tried this.
Here are some visual directions to #CameronLowellPalmer's answer.
I got the steps from
#WayneHenderson's comment underneath the accepted answer.
Follow the red arrows steps 1 - 11 (there is no 8, I made a mistake and went from 7 straight to 9).
The most important thing is step 4, make sure to select All or you won't find the Other Code Signing Flags options.
For step 5 just enter Other Code Signing Flags into the search container.
Steps 9 - 11 is where you enter --generate-entitlement-der
You will need to add the --generate-entitlement-der to your OTHER_CODE_SIGN_FLAGS under Build Settings.
Xcode > Target > General
Section "Embedded Framework, Libraries and Embedded Content"
Set all frameworks in the Embedded field to "Do not Embed"
For people who use Xcode13 like me, the problem may not be because of the code signature of our apps (To check the code signature of apps, see https://developer.apple.com/documentation/xcode/using-the-latest-code-signature-format), but due to the code signature of one of the dependencies, and removing the dependency solves the problem.
In my case, I remove the dependencies one by one, and eventually found that the culprit is FirebaseAnalyticsOnDeviceConversion. remove dependencies
I have spent 2 days to find this issue, Finally i got the solution here from the person Lance Samaria. I would like to share it.
Target-> Build Settings -> Other Code Signing Flags
Add this code --generate-entitlement-der to both Debug and Release
After that Go to Target-> General->Frameworks, Libraries, and Embedded Contents -> Change to "Do not Embed"
Also I renewed Provisioning Profile and IOS Distribution Certificates.
Now Clean Build Folder and Run Your Project.
Thank you so Much for Lance Samaria
I want to share my solution. This worked for me using XCode 12.3, macOS Catalina, and tested using Adhoc distribution.
Build, archive, export ipa as usual using XCode.
Now you have the IPA file, then rename it to zip extension. (make a backup if needed)
Extract it. There should be a Payload folder.
Open terminal, cd to your IPA directory, then run command:
codesign -s "CERTIFICATE_NAME" -f --preserve-metadata --generate-entitlement-der ./Payload/YOUR_APP.app
CERTIFICATE_NAME is your certificate name located in keychain. It maybe looks like this: Apple Distribution: XCompany (XXXXXX)
YOUR_APP is your .app file name located in Payload folder.
This warning showed up, I ignored it.
Warning: default usage of --preserve-metadata implies "resource-rules" (deprecated in Mac OS X >= 10.10)!
Then run zip command:
zip -ru myapp_resigned.ipa Payload
Done. You can redistribute the new IPA.
After testing all solutions, Only one worked for me. Because XCode adds sign signature automatically when you add Framework, Any Framework that needs to Embed & Sign should remove, and add again. Xcode will add the new sign signature automatically.
Go to YourTarget>Frameworks, Libraries, and Embedded Contents.
Remove all frameworks that are Embed & Sign, except CocoaPods.
add removed frameworks again and set to Embed & Sign.
check that pods framework set on Do Not Embed
Now clean and run your app on your device.
What helped in my case was pod deintegrate and pod install. That's all.
I had this problem with the newest Xcode version (13.4.1). As the installation on an iOS device actually stoped working out of nowhere (it did install successfully 10 min ago before I downgraded one dependency), I doubted the proposed solutions relate to my problem.
Just my two cents.
As pointed out in other responses, now to sign ios app (compatible with ios and ipados 15) with codesign command on MacOS prior to Big Sur add the --generate-entitlement-der flag. I can sign my app with Xcode 10.3 using this python 2.7 (tried both on MacOS Mojave 10.14 and MacOS Catalina 10.15) snippet code:
from fabric.api import local
local('cp %s "%s"' % ("/path/to/embedded.mobileprovision", app_full_path))
local('xattr -rc %s' % app_full_path)
local("codesign -f --generate-entitlement-der -vv -s \"%s\" --entitlements \"%s/Entitlements.plist\" %s" % (
env.code_sign_identity, app_full_path, app_full_path)
)
Output example log:
[localhost] local: cp /path/to/embedded.mobileprovision "/path/to/Payload/appname.app"
[localhost] local: xattr -rc /path/to/Payload/appname.app
[localhost] local: codesign -f --generate-entitlement-der -vv -s "iPhone Distribution: COMPANYNAME S.p.A." --entitlements "/path/to/Payload/appname.app/Entitlements.plist" /path/to/Payload/appname.app
/path/to/Payload/appname.app: replacing existing signature
/path/to/Payload/appname.app: signed app bundle with Mach-O universal (armv7 arm64) [com.name.reverse.dns]
Some additional tips...
MacOS keychain should contains the Apple certificate used to create the mobile provisioning profile, which is also utilized to distribute the app we’re signing. You can check it using the command security find-identity -p codesigning:
$ security find-identity -p codesigning
Policy: Code Signing
Matching identities
1) AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "iPhone Distribution: COMPANYNAME S.p.A."
...
13) CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC "iPhone Developer: Name Surname (DDDDDDDDDD)"
13 identities found
Valid identities only
1) AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "iPhone Distribution: COMPANYNAME S.p.A."
...
13) CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC "iPhone Developer: Name Surname (DDDDDDDDDD)"
13 identities found
After the ipa zip archive creation, you can use the Gem ipa_analyzer (https://github.com/bitrise-io/ipa_analyzer) to verify if the app is correctly signed:
$ zip -9 -y -r /path/to/appname.ipa /path/to/Payload
$ gem install ipa_analyzer --user-install
$ PATHAPP="/path/to/appname.ipa"
$ ~/.gem/ruby/2.6.0/bin/ipa_analyzer -i ${PATHAPP} -p --info-plist --prov | grep -E "ExpirationDate|CFBundleIdentifier|DER-Encoded-Profile"
"DER-Encoded-Profile": "#<StringIO:0x00000f0000000008>",
"ExpirationDate": "2022-09-18T12:15:25+00:00",
"CFBundleIdentifier": "com.name.reverse.dns",
...
Here a complete output example.
As additional references about this issue, you can read also this Apple documentation page and this Apple forum post.
EDIT: this procedure it's working also with MacOS Monterey (version 12.6.1) and Xcode Version 14.1 (14B47b).
The following changes solved my problem
Go to Project Target and select General
Scroll down to Frameworks, Libraries, and Embedded Content
Turn any Embed & Sign to Do Not Embed
My issue was I was using custom framework, and when I embed it in my app. it showing me error
The code signature version is no longer supported.
i spend whole day to struggle with it. Finally resolved it by adding user-defined settings. In new Xcode 13 which supports arm 64
Project target->Build Settings-> + sign to add user define setting and add a setting. then add VALID_ARCHS as a field under this add the value $(ARCHS_STANDARD). Automatically it will convert it arm64 arm 7.
see the attached image for more reference.
When nothing else works, try turning your device off and back on again. Strangely this finally fixed it for me.
My issue was I was using custom static framework target, and I embed it in my app, Finally resolved it by don't embed it or change static to dynamic framework target
Maybe it will help somebody one day, but the solution for me was connected with the pods and their framework.
When I switched settings to Do not embed everything worked.

Building for iOS Simulator, but the linked framework '****.framework' was built for iOS

I cannot run my app on simulators anymore. Online suggested that I edit my project.pbxproj, but that does not appear to work. How do I reclaim the ability to run my project on my simulator (and remain able to do so on a device)? I am working on another project that uses many of the same frameworks, but it runs on a simulator. What would cause a similar framework to work in one project but not in another?
Xcode 12.3
In my case I solved this problem by simply setting Validate Workspace to Yes in the Build Settings tab
No doubt that the fix in case of Xcode 12.3 is to setup the Validate Workspace property in the target's build setting. However if you check the diff after this change, the reason of the build error is the missing parameter (VALIDATE_WORKSPACE) from the project file, not the value of the parameter.
So you don't need the value to be YES. You need to add the value to the project settings and you can leave it on the default value (NO). At the first time, it shows up in the Build Settings with NO, but only because that is the default value of the missing parameter.
TLDR;
Without changing your project setup, go to your target's build settings, find "Validate Workspace", set it to YES, then set back to NO.
It happened to me when I added my custom framework into the project and after I updated my Xcode, I encountered the same issue.
Solution : under build settings in project search for Validate workspace Just
change to yes which is by default set to no
Use a .xcframework rather than a "fat" .framework containing an iOS and iOS simulator slice.
This also obviates the need to use a build phase to strip the iOS simulator slice when building for the App Store.
"Fat" frameworks, which are typically created using lipo as they cannot be built directly by Xcode, are not supported (source: Developer Technical Support Apple Developer forum). .xcframework is the only supported mechanism to ship a single framework supporting both iOS and the iOS simulator.
Also .xframework's is the only supported way to ship a binary Swift framework (source: Developer Technical Support on Apple Developer forum).
In Xcode 12.3, the fact that "fat" frameworks are non supported is enforced, as Xcode verifies the frameworks during build, which is why a lot of projects suddenly started to see build errors.
Most answers here are for consumers of universal binaries to work around the new restrictions. But, as in noted elsewhere, it's time to migrate to Apple's XCFramework format for framework authors.
If you were running a custom build script to create universal binary before with an aggregate target and lipo, it's straightforward to migrate to producing .xcframework files
First, in build settings make sure "Build Libraries for Distribution" (BUILD_LIBRARY_FOR_DISTRIBUTION) is set to YES
Then, replace your existing aggregate target build script that used lipo with something like the following which is simple for showing how to make "release" frameworks only:
# Universal Script
set -e
FRAMEWORK_NAME="your_framework_name"
IOS_SCHEME_NAME="your_scheme_name"
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi
SIMULATOR_ARCHIVE_PATH="${SRCROOT}/build/${FRAMEWORK_NAME}-iphonesimulator.xcarchive"
DEVICE_ARCHIVE_PATH="${SRCROOT}/build/${FRAMEWORK_NAME}-iphoneos.xcarchive"
OUTPUT_DIR="${SRCROOT}/framework_out_universal/"
# Simulator xcarchieve
xcodebuild archive \
-scheme ${IOS_SCHEME_NAME} \
-archivePath ${SIMULATOR_ARCHIVE_PATH} \
-configuration Release \
-sdk iphonesimulator \
SKIP_INSTALL=NO
# Device xcarchieve
xcodebuild archive \
-scheme ${IOS_SCHEME_NAME} \
-archivePath ${DEVICE_ARCHIVE_PATH} \
-sdk iphoneos \
-configuration Release \
SKIP_INSTALL=NO
# Clean up old output directory
rm -rf "${OUTPUT_DIR}"
# Create xcframwork combine of all frameworks
xcodebuild -create-xcframework \
-framework ${SIMULATOR_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \
-framework ${DEVICE_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \
-output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework
# Delete the most recent build.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi
You can tweak the above to have different output dirs, different deletion behavior, support multiple configurations (Release vs Debug) but this works for me.
Finally, as a one time step, delete the your_framework_name.framework universal binary that caused you the error as mention in this project. Copy the newly built your_framework_name.xcframework and add it to the project and the error should go away.
possible reason would be
framework which you are using may not be built for simulator architecture(x86_64), you can check the compatibility by going to framework folder (framework_name.framework --> modules --->framework_name.swiiftModule-->) in this path you should see arm/i386/x86_64 support files
if you have updated to new Xcode, the frameworks you are using are not compatible to the newer compiler version, so vendor needs to share the recent compatible one, in this case you will not be able to run on both device and simulator
To be honest, the only approach that you guys should follow is to convert .framework to .xcframework, as this is what Apple enforces from XCode version 12.3 and above. Validating workspace and other quick fixes may be temporary and cause problems in the future - like archiving the app for appstore release or testflight.
To convert .framework to .xcframework follow the steps described in the article, starting from paragraph Commands:
https://medium.com/strava-engineering/convert-a-universal-fat-framework-to-an-xcframework-39e33b7bd861
I ran in this error on Xcode v12.3 and Universal(fat) Framework(.framework)
Building for iOS Simulator, but the linked and embedded framework was built for iOS + iOS Simulator.
Solution 1: is Toggle/Toggle Validate Workspace(not default)
Solution 2: use XCFramework[About]
If you are using Carthage, make sure you use the copy-frameworks script rather than using Embed & Sign as embedded content. I was getting this same error because I forgot about that.
I suppose the framework you are linking was built only for arm architecture. You won't be able to run it in a simulator. You will need an author of the framework to build a "universal framework".
If you are new to Xcode and using Xcode just to launch emulator to run appium tool the above steps might be complex. Just use xcode version less than 11 for beginners.
This link helps to download xcode 10.3
Xcode10.3
If you try to download from AppStore we need to have free storage up to 40 GB the above `xip file will won't cause storage errors.
You can Thank me later if this works!!

Xcode app distribution fails after update of OS and Xcode

I have such an error in the organizer while distributing my app. The app builds and works ok in Debug mode on simulator or iPhone. It also Archived but I cannot distribute it via Development distribution from organizer!
ipatool failed with an exception: #<CmdSpec::NonZeroExitException: $ /Applications/Xcode-beta.app/Contents/Developer/usr/bin/python3 /Applications/Xcode-beta.app/Contents/Developer/usr/bin/bitcode-build-tool -v -t /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin --sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.4.sdk -o /var/folders/ls/0vdttqm92zq1rtcsjntc4mxw0000gn/T/ipatool20200210-7826-1kq2c5j/thinned-out/arm64/Payload/CRM\ Dev.app/Frameworks/GoogleUtilities.framework/GoogleUtilities --generate-dsym /var/folders/ls/0vdttqm92zq1rtcsjntc4mxw0000gn/T/ipatool20200210-7826-1kq2c5j/thinned-out/arm64/Payload/CRM\ Dev.app/Frameworks/GoogleUtilities.framework/GoogleUtilities.dSYM --strip-swift-symbols /var/folders/ls/0vdttqm92zq1rtcsjntc4mxw0000gn/T/ipatool20200210-7826-1kq2c5j/thinned-in/arm64/Payload/CRM\ Dev.app/Frameworks/GoogleUtilities.framework/GoogleUtilities
Status: pid 8359 exit 2
Stdout:
SDK path: /Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.4.sdk
SDK version: 13.4
UPDATE
If I uncheck Rebuild form bitcode then it distributes. But I think it can cause problem later if I want to distribute app to App Store?
need to check the transporter App Apple launches to upload the apps to app Store
https://developer.apple.com/news/?id=10152019a. It's going to help
iOS 13.4 is a beta version. The app store doesn't accept builds created with beta versions.
We've got similar issue, which is described here. No needs to distribute without bitcode. Long story short, there were LLVM instrumentation included, which prevents AppStore processing. I've written a whole blog about XCode 12 and BigSur issues with XCFramework.
To sum up, here is a few required steps to make sure while creating XCFramework for distribution:
Using archive builds is a MUST, release build isn't enough
BUILD_LIBRARY_FOR_DISTRIBUTION must be set to YES
SKIP_INSTALL must be set to NO
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO to turn off GCC instrumentation and remove them from the binary
CLANG_ENABLE_CODE_COVERAGE = NO to turn off code coverage tools from the binary
Having all of the above helped to solve our preparing and distribution problem and hopefully save you some time if you happened to face same issues as we did.

How to install iOS application from src, .app, or .ipa via command line to hardware device

For test automation (GUI test, not XCUnitTest) purposes, I need to install an iOS app onto a physical hardware device.
I'm looking for:
a replacement to Fruitstrap (it has been abandoned)
or a way to perform XCode's "Build & Run" action on a target device
I've tried:
using xcodebuild and pointing the -destination argument at the target device and providing build actions of clean and install
It finds the target device and begins cleaning and then installing.
At the end of all the files being compiled and the app being signed, I get a success message
** INSTALL SUCCEEDED **
But, alas, no app is installed on my phone.
This is my full xcodebuild command:
xcodebuild
-destination platform=iOS,id=######## \
clean install
Here's the gist of the output
Creative suggestions welcome.
I'm considering writing an applescript if needed, but wish there was a better way.
Fruitstrap is, for the time being, working and installing the app correctly.
/path/to/fruitstrap \
install -id ##udid### \
--bundle "/Users/#######/path/to/application.ipa"
Other, more maintained solutions are still welcome.
Limitations:
Need to have a prebuilt .ipa file
Target device must be signed with a provisioning profile that includes the target device's udid

iOS Enterprise: Re-certify existing IPA with new certificate

We are enrolled in the iOS Enterprise Program. The provisioning profile used for our released apps is about to expire, so I got a new certificate and provisioning profile.
I need to re-distribute some of our apps with the new provisioning profile, without building them anew. How?
(I vaguely remember seeing a utility program that did exactly this: You choose an IPA and a provisioning profile, and it would create a new IPA using the new profile and certificate. What was the tool’s name, and where can I get it?)
In theory whoever built the last IPA in XCode should have used Archive - this creates a build you can sign to create an IPA (using XCode).
You could also try using the command line signing tool XCRun to re-sign the App bundled in your existing IPA:
http://skabber.com/package-your-ios-application-with-xcrun
OK, turns out when you know what term to google, there‘s lots of excellent resources…
They all point to xcrun. I made it work with this shell snippet, adapted from this promising build script:
APP_FILENAME=MyApp.app
BUILD_DIRECTORY=/Path/To/Target/Dir
IPA_FILENAME=MyApp.ipa
DISTRIBUTION_CERTIFICATE='iPhone Distribution'
PROVISIONING_PROFILE_PATH='/Path/To/Profile.mobileprovision'
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "$APP_FILENAME" -o "$BUILD_DIRECTORY/$IPA_FILENAME" --sign "$DISTRIBUTION_CERTIFICATE" --embed "$PROVISIONING_PROFILE_PATH"
The codesign command-line utility, included with the iOS SDK tools, will allow adding/changing the certificate and provision with which a developer built app is signed.
As hotpaw2's anwaswer states. You can also resign using the codesign tool.
The way I do it (this may not be the most efficient, but it works)
Rename the .ipa to a .zip and extract
Run The following:
/usr/bin/codesign -f -s "iPhone Distribution: Company Name" "Payload/MyApp.app"
Re-zip the Payload folder and rename to .ipa
Note: You can also use this method to edit the embedded.mobileprovisioning file! Just remember to remove the .DS_Store (rm Payload/.DS_Store) if you are using finder.
You can do manual way if you just resigning app from same account with following steps.
All this is using shell script and super easy provided you know how to use shell commands.
Rename IPA to zip
unzip this file to temp folder
Remove the old _CodeSignature folder from all targets (if you have multiple targets like main,watch, watch extn, siri, widget, message, etc)
bring all the targets prov-profiles in one folder and replace all the embedded.provisioningprofile files for each target with the new ones
remove the archived....xccent file as this is old one (optional)
code sign with the entitlements.plist created for all the entitlements if any used by the app.
Zip the folder back after code sign all okay with no errors
Rename the zip to IPA
Note: To validate the IPA before upload to apple you can just use the altool from inbuild XCode App Loader to check the new IPA.
Reference: The steps for commands is also explained here:
http://www.enterpriseios.com/forum/topic/Resigning_3rd_party_apps
If you want to get rid of manual sign use the fastlane tool as its quite simple and easy to configure.https://fastlane.tools/

Resources