IPA File Structure - SupportSwift & Symbols - ios

When unzipping the ".ipa" file, the output is: Payload directory that contains the application. However, sometimes the output is: Payload, SwiftSupport and Symbols directories.
What are the conditions to generate both SwiftSupport and Symbols directories?
Also, I noticed that SwiftSupport contains .dylib files, which -I assume- they are already exist in the application (right click -> show package contents -> frameworks), so:
The application should work fine even if they are not exist, what are the purpose of generating them?
I couldn't find any useful reference to describe what I'm looking for.

After playing with archiver I found answers for all your questions.
What are the conditions to generate both SwiftSupport and Symbols directories?
SwiftSupport folder is managed by option ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES from target's Build Settings
Symbols directory is managed by checkbox on export dialog:
Since Xcode 7 there is also support for exportOptionsPlist with symbol export option for command line build, more details here
Second part is more interesting:
The application should work fine even if they are not exist, what are the purpose of generating them?
Answer to this question I found in ... apple's documentation:
Always embed the Swift standard libraries in the target's products, even if the target does not contain any Swift code. For example, this should be enabled if the target is embedding other products which contain Swift, or if it is a test target which does not contain Swift but which is testing a product which does. This setting only applies to wrapped products, not to standalone binary products.
So application's .ipa can contains this folder with libraries even without using of swift directly

As sage444's answer give your some explanation to your answer. There are few points that I have observed.
Symbols: You need this folder to symbolicate your crash logs.
SwiftSupport: Although you have two copies of dylib one in Payload and other in framework. But when you upload it to iTunesConnect then the size of your downloadable app is less than the size of your ipa file. The iTunesConnect manages your duplicate items (dylibs).
For more info you can check this answer

Related

What is .symbol files in IPA

I've IPA which is uploaded on AppStore. On unzipping IPA I see two folders
Payload and Symbols.
Symbols folder contains many files with extension .symbol
Any idea what would be these symbol files? Can we use them for symbolication?
Yes, it is debug symbols. They contain a mapping between encoded names and locations in your compiled code and the original function names among other debug information. Each <UUID>.symbols file represents either the main binary of you app or a framework that your app is using. You can find out which is which using mdfind (see example).
See this about symbolication

How to reduce the size of my custom iOS framework?

I'd created a custom framework in iOS, with swift4 in Xcode 9.2. The framework contains 9 .swift files, when I tried to archive and create a .framework file, the resultant shows a size of 5MB. However, the 9swift files totally shows a file size of just 72KB. The archived, .framework file is too big in size(5 MB) which my client doesn't agree with.
I'd tried to remove the unwanted code but still the size remains the same, they want me to make it like that of Android framework, which is just 34KB of size. This is the first time I'm creating a framework and I'm out of solutions, can someone help me to reduce the size of the framework without reducing the files?
There are two things I've tried and it has worked for me. Maybe it can also be useful for you.
The linker exports all the symbols by default. You can limit that through some techniques discussed in this article about Symbol Visibility. Also, there is a nice feature in the linker that allows you specify with symbols must be exported or not exported. Exporting only the interface symbols might help you reduce size and your client not waste memory.
So, in practice:
Considering that my framework archive is MyFramework.framework.
I've listed all symbols of MyFramework.framework/MyFramework by running $ nm -g MyFramework.framework/MyFramework and selected the symbols that my binary needed to export (symbols my client would need to access).
All selected symbols were saved in a text file. So assuming that among all the symbols listed, you'll need to save to the text file only the ones you need (your client needs).
Open MyFramework project and set Build Settings -> Exported Symbols File to point to the text file you just created.
With the binary in hands, you can strip some symbols using strip -N MyFramework.framework/MyFramework.
In my case I could achieve something good but I think it might change from project to project. Also, I was dealing with Objective-C. I made a sample Swift project with the results achieved. You can check it out at https://github.com/gbazilio/ios-framework-size.
Hope it helps for you as it did for me.

$(AppIdentifierPrefix) is not resolved during build time

$(AppIdentifierPrefix) in .entitlements file is not getting replaced with the actual AppIdentifierPrefix. Can someone please shine some light onto this issue?
So here is my understanding of the YourApp.entitlements file that gets added to your project when you add capabilities like iCloud or Game Centre to your application.
(I'd love to see some pointers to official documentation ... if any exists.)
What are these entitlements files used for?
So first of all, the .entitlements is only in your project for the build process. It should not end up in the final .app product. If it does, select the .entitlements file and in the File Inspector, clear it's Target Membership. (This is how Xcode generated these files actually, without any target membership)
So what is the .entitlements file used for then? It is part of the build process where it is taken and processed and put in your final application bundle in two forms:
First: the contents of the .entitlements file is embedded in the embedded.mobileprovision file. This is a signed property list with a binary signature on top but if you open it up in a text editor you can see there is a <key>Entitlements</key> section that should have the processed entitlements in there.
Second: there is also a copy of the .entitlements file called archived-expanded-entitlements.xcent. This is essentially the same file as the original .entitlements file except that it has been processed.
What preprocessor values can be used in the .entitlements file
I don't think the processing of the .entitlements file is documented anywhere. There most certainly is a pre-processor running over it, so that things like $(AppIdentifierPrefix) are replaced with the actual value. However, this seems to be not the same as the one that is used for the Info.plist file.
The $(AppIdentifierPrefix) is the same as the Team Identifier that you may have configured in your Xcode project. You can find the configured Team under your target's General settings in the Identity section. If team is set to None then there is a good change that $(AppIdentifierPrefix) won't be set.
So to finally answer your question: if you look at those two files that I mentioned above, and you still see the $(AppIdentifierPrefix) is not correctly substituted, make sure your project has a Team Identifier configured.
How does Xcode know what entitlements file to use for your target?
In your build settings you can look at the Code Signing Entitlements settings to find out what file Xcode uses for each build configuration. Usually Debug and Release use the same entitlements file but you can change that.
(For example, for Firefox for iOS we have build configurations for Nightly, Aurora, Beta and Release builds. These all have different entitlements files. The reason we have different entitlements files is because we could not make the .entitlements pre-processor recognize settings like $(PRODUCT_NAME:rfc1034identifier) - i'd love to hear if there is a way to do that because that will make our build simpler.)
What tool processes the .entitlements files?
Not entirely sure. But if you look in the build logs, you will see some reference to a builtin-productPackagingUtility tool. This seems to be an internal Xcode command, not something actually present as a command line tool. So that is not very useful.
Now you know pretty much everything that I know about .entitlements files :-)
(I'd love comments and turn this answer into the definitive guide to entitlements files - i think there is a lot of confusion around them)

Integrating .a library file types with XCode

I am testing an image capture library that sent over their code library as a regular header file and a file ending in a "*.a" extension. I am not familiar with using a file in this format and can't seem to find the right "magic" to search for.
What does this file extension stand for?
What if any extra steps are needed to get it integrated with my XCode project?
Maybe a bit more of theory can get you in the right track so you'll know how to search next time:
.a files are archives of object (.o) files. These object files are generally produced by an assembler, compiler, or other language translator; They contain machine code that is usually not directly executable, but are used by linker tools to generate an executable or yet another library by combining parts of these object files.
Another important thing you should know is that since these files contain machine code, they must have been compiled for the correct architecture you're targeting for (ex.: armv7, i386, etc). That can be the reason why sometimes you will be able build your project for one device but not to another if you don't have the right set of files for the targeted platform (e.g. iPhone simulator vs. actual iPhone).
It is also possible to have "universal binaries", which are files that in turn package together archives of object files (.a) for different architectures (e.g. using tools such as lipo), so that the same library file can be given to the linker for multiple architectures. Or, you may have a different linker configuration for each target (e.g. using conditional build settings in XCode). All of these files can be analyzed with certain tools (e.g. "file", "otool", "lipo -info", etc), and each has several parameters to play with. Debuggers will also check the symbols within these files for their own purposes.
When you drag the '.a' file to your project's directory within Xcode, you can notice that it will automatically add this file to the list of "Link Binary With Libraries" items under your target's "Build Phases".
Since the header files allows us to separate certain elements of a program's source code into reusable files, that commonly contain forward declarations of classes, subroutines, variables, and other identifiers that are needed for reference during the compilation step, it is common to have libraries provided as archives of compiled objects (.o) in ".a" files along with their respective headers. For instance, as soon as you include the headers files in your XCode project, the editor will provide auto-complete for these new functions.
Sometimes, you might also consider having the actual source code of the library instead of binaries inside your project as this * might * make debugging easier in case an unexpected behavior is happening inside that "library" package. Many times this is not an option though (when you have no access to the sources) when the binary distribution is made in purpose to hide implementation details (commercial libraries).
.a stands for archive. It is also known as a static library. I believe you should be able just to drag it and the header files into Xcode. Xcode should pick up the right thing to do from its extension.
Example, see appr. from 30 sec here
http://memention.com/ac3dreader/usage/quickstart.html
Another example from Google Analytics, under Setup
Drag GANTracker.h and libGoogleAnalytics.a from the SDK's Library directory into your new project.
https://developers.google.com/analytics/devguides/collection/ios/devguide

XCode adding duplicate and incorrect icon filenames to Info.plist

When I run the XCode 'Archive' command, I get seven error messages about missing files. Most are for the launch files that are supposed to be there, but one contains the misspelling "Portait".
warning: Icon specified in the Info.plist not found under the top level app wrapper: Default-Portait~ipad.png (-19007)
Unable to validate your application. - (null)
I did enter that filename by mistake several months ago, but I thought I expunged it from the project. Here is the 'Info.plist' file for my app. Note that it has no icon entries, other than Icon file.
Here is my Target Summary. I have launch images specified.
When I look at the 'Info.plist' file within the newly created archive, it contains a whole list of icons. I've showing Icon files (iOS 5) here, but the list is duplicated under Icon files. The "Portait" misspelling is there, as are several duplicates. It's mess.
I know that XCode automatically generates some content for 'Info.plist', but where is this long list of filenames coming from? And, how can I prevent them being generated?
What I Have Tried
I have run 'Clean' and deleted my XCode 'DerivedData' directory, but the warning messages and spurious Info.plist entries persist.
I checked the localized 'InfoPlist.strings', but it only contains the line /* Localized versions of Info.plist keys */.
I looked through the contents of my '.xcodeproj' package, but found no mention of the files it's trying to find.
I tried adding an empty array of icon files to my 'Info.plist', or adding the names of the exact files I wanted. The bad and duplicate names still get appended to the end when I Archive.
I tried duplicating the Target (which, as usual, duplicated the existing Info.plist file). Archiving the new target resulted in the same error.
The Build Setting Preprocess Info.plist File was off. I tried switching it on; it made no difference.
I tried switching off the Build Setting Expand Build Settings in Info.Plist File. It told that I was trying to run the file '${EXECUTABLE_NAME}'. I went to my 'Info.plist' and changed Executable file from '${EXECUTABLE_NAME}' to a hard-coded text value, and also manually replaced the other '${...}' entries. Despite this, it persists in trying to run '${EXECUTABLE_NAME}'. Possibly whatever is adding to the icon settings is also overriding my executable name.
What I Would Rather Not Do
I could probably suppress the warning by adding files to the project with the names it expects, including Default-Portait~ipad.png. I'd really rather stop it these names being added to 'Info.plist' in the first place, since those duplicate entries could cause other problems down the line.
Other Details
This project was created in early 2011, and has been progressively migrated through newer versions of XCode. It is currently open in XCode Version 4.3.2 (4E2002).
Found it: choose a Target and go to the 'Info' tab, and you get something that looks like 'Info.plist'... but changes made there can override your Info.plist. This was especially confusing because I had intentionally made multiple Targets share the same 'Info.plist' file, to avoid needing to make the same change in multiple places.
I would still welcome an explanation of where these settings are stored within the '.xcodeproj' package.
I have the same issue -- Xcode did this to me for a new project. My info tab on the target shows the same mess. I guess I will check for updated iOS6 docs and edit the entries here to the best form.

Resources