What is .symbol files in IPA - ios

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

Related

Does an iOS extension have an IPA file?

I was wondering if a share extension creates an .ipa file similarly to a regular target?
Thanks
No, it's packaged in your app's IPA and delivered to Apple as a single file with it (and everything else).
An IPA itself is a zip format file -- if you make a copy of one and rename it to .zip, you can unzip it and look at what it has.
At the top level it has a Payload folder with a .app file in it. That file is a package (you can right-click and show contents). In there, you'll find a PlugIns folder, which will have *.appex files. These are what your extension targets build.
So, the IPA's Payload/NAME.app/PlugIns/*.appex packages are the extensions.

IPA File Structure - SupportSwift & Symbols

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

Can I extract a library .a into a iOS project from .ipa?

I have an app installed, I have the .ipa and I have this question: is possible extract a static library file added to this application?
This application contains a static library in format .a, images and the files. I know how to extract the images from the .ipa and I know that is possible get the functions with reverse engineering, but I don't know if is possible extract the library added, because I only see binary files and images then extract .ipa, but I don't see the .a files.
No. The app binary is all of your code and static libraries all combined (linked) into a single binary. There is no way to extract any specific library from the resulting binary.

What's the difference between DWARF and DWARF with dSYM file?

XCode supports those 2 values for this Build Setting:
Build Settings > Build Options > Debug Information Format.
Could anybody explain the differences?
The difference is that in the case of DWARF with dSYM file your Archive app.xcarchive (for adHoc distribution) contains also dSYM file needed for reverse symbolication of your code in crash reports. In general, .xcarchive contains
dSyms
Products
info.plist
So if you need it for external analysis of crash reports under archiving you app for distribution you should use DWARF with dSYM file.
As always understanding the abbreviations help!
DWARF is a widely used, standardized debugging data format:
DWARF was originally designed along with Executable and Linkable Format (ELF), although it is independent of object file formats. The name is a medieval fantasy complement to "ELF" that has no official meaning. Only that both (dwarf and elf) are mythological creatures
Debug Symbol (dSYM):
By default, debug builds of an application store the debug symbols inside the compiled binary while release builds of an application store the debug symbols in a companion dSYM file to reduce the binary size.
The Debug Symbol file and application binary are tied together on a per-build-basis by the build UUID. A new UUID is generated for each build of your application and uniquely identifies that build. Even if a functionally-identical executable is rebuilt from the same source code, with the same compiler settings, it will have a different build UUID.
For example, if you have a library libfoo.dylib, the debug symbol file
would be libfoo.dylib.dSYM.
From here
So long story short
DWARF is just a debug file
DWARF with dSYM File is a debug file along with symbolification file
DWARF is embedded in the object files of the binary, but not in the binary itself (unlike stabs, which are linked into the binary proper). dsym extracts the DWARF info from the object files, puts it in a separate dSYM bundle and makes the binary refer to this bundle (instead of to the object files). Docs
Also see DWARF's official home page
Pro tip:
On our project's GitHub repo, on the releases section we have something like this:
We upload the .ipa and dysm file so then if 3 months from now a user has a weird crash for our 10.16 build then we'd go to this release branch and run it with this dsym and try to reproduce the issue.
Both DWARF and DWARF with dSYM create DWARF debug information like on all other platforms, but they differ on where the debug information will be accessed when debugging or symbolicating:
DWARF means that the debug information is left in .o files and this debug information is not linked during the build process. Each .o file will contain unlinked DWARF and the debugger (LLDB, GDB) will link the debug information on the fly when debugging. The main executable contains a debug map contained in the symbol table which has everything that is needed to link the debug information. The maps contains STABS symbol entries that points to each .o file and tells the debugger or linker where everything needs to be linked (for functions, globals and static variables). The debug information will be less efficient since it is not linked, and each .o file can contain type definitions that are also found in other .o files, so the overall debug information size will be bigger. This is often most useful for the edit/compile/debug cycles for when you're implementing new features or trying to track down bugs. The benefit is you do not have to link the debug information during your build process. Not all tools that parse debug information support this mode of debug information, so you might want create dSYM files if local crash reports on your system do not contain source file and line information in the backtraces. Tools like sample, ReportCrash, and Instruments that need to parse debug information might not support the DWARF setting.
DWARF with dSYM means that after you build your executable, a dSYM debug information file will be linked using a tool named dsymutil. dsymutil gets ran after your executable is linked to parse the debug map in the main executable and produce a dSYM file with all of the debug information. Linking the debug information can add to your build times if you have a lot of code in your project. The DWARF debug information in all of the .o files is intelligently linked into the dSYM file. Any code that was dead stripped will have its debug information removed, and the dsymutil will dedup types within the debug information, so the resulting DWARF is much smaller and more efficient. Use this setting when building your releases or if you have a build machine that is caching builds for others to download.
In order to find the dSYM file for an executable, the UUID from the main executable is copied into the dSYM file. A previous comment suggested that the UUID changes with each build even if the same source code and compiler was used, but this is not true. The UUID is a MD5 checksum of the parts of the binary that do not change due to debug information. Debug information can contain paths and other data that change depending on what directory the sources exist in. If the UUID was simply a MD5 checksum of the entire binary, then the UUID would be different for the same sources built with the same compiler if one was built in /tmp/myproj vs /users/data/myproj. So the UUID built into Darwin binaries will match if the important bits (__TEXT, __DATA, etc) are the same even if the project is built in different directories. This allows the UUID to be used to unique dSYM files across multiple builds that produce the same binary. If SDK header files or different compilers or linkers are used, the UUID can easily differ.
There is Spotlight importer for dSYM files knows how to extract the UUID from the dSYM file to make it possible for debuggers and other tools like sample, Instruments, ReportCrash and more to find the dSYM file for a binary even if the dSYM file is not right next to the binary. You can see the UUID of your binary by running dwarfdump:
$ dwarfdump --uuid ~/a.out
UUID: E76A2647-AFB4-3950-943A-CB1D701B7C07 (x86_64) ~/a.out
Then you can use the Spotlight window in your system to search for the dSYM file. There is also a command line tool for spotlight called "mdfind" that can be used:
$ mdfind E76A2647-AFB4-3950-943A-CB1D701B7C07
/Users/admin/a.out.dSYM
So to sum up: use DWARF for edit/compile/debug cycles if you have large projects and want to avoid the time it takes to link a dSYM file during your daily workflow. Use DWARF with dSYM all the time if you have smaller projects, doing release builds, or need other Apple tools that are not debuggers to be able to parse your debug information. Both formats contain the same kind of information and can be used for debugging, but not all tools can load the DWARF format where the DWARF is left in the .o files.
DWARF (debugging with attributed record formats) is a debugging file format used by many compilers and debuggers to support source-level debugging. It is the format of debugging information within an object file. The DWARF description of a program is a tree structure where each node can have children or siblings. The nodes might represent types, variables, or functions.
source: https://www.ibm.com/developerworks/aix/library/au-dwarf-debug-format/index.html
DWARF with dSYM File stores the debug symbols for your app
Services like crashlytics use it to replace the symbols in the crash logs with the appropriate methods names so it will be readable and will make sense.
source : What's the dSYM and how to use it? (iOS SDK)
From "Project Editor Help":
Debug Information Format (DEBUG_INFORMATION_FORMAT)
The type of debug information to produce.
DWARF: Object files and linked products will use DWARF as the debug information format. dwarf
DWARF with dSYM File: Object files and linked products will use DWARF as the debug information format,and Xcode will also produce a dSYM file containing the debug information from the individual object files (except that a dSYM file is not needed and will not be created for static library or object file products). dwarf-with-dsym

Why is a static library 10Mb, but an .ipa using it is only 4Mb?

I have a workspace that contains a static library and a project using the library, I'm then building the project (using Jenkins) to create an archive for ad-hoc distribution.
The resulting file size for the built library is reported as being 10.4Mb, yet .ipa is reported as being 4.2Mb.
How can the .ipa be so much smaller than the library, and yet the app runs when installed so it must be containing the library.
This have multiple reasons:
Static libraries contains additional information required for linking (like methods names and so on).
IPAs are compressed archives. Similar to ZIP just with another file ending.
The most likely explanation is that the library contains symbols necessary to linking (as well as debugging symbols, possibly), while the ipa file has been already linked (thus it does not contains information for the linker) and stripped of debugging symbols.
On another account, the ipa file is just a zip file, so its content is also compressed.
The algorithm that apple uses to compress into .ipa is very good .
If your bundle doesn't contain too many images the percentage can be as low as 15% (from the uncompressed size on disk).

Resources