8

Having added TwilioVideo as a Pods dependency in my iOS project, I realized that its size significantly increased (+100 Mo).

After some researches, I found this thread and especially this message that advises stripping bitcode using this command via Podfile.

I didn't know much about bitcode, until I found this great article about it: https://lowlevelbits.org/bitcode-demystified/

Now I understand what is bitcode and why Apple requests it as well as how they use it to recompile apps if they want to. However, I still don't understand what is this "strip bitcode" operation, so I'm looking for information about this (it actually worked well since after adding these lines to my Podfile, my app is now "only" 30 Mo bigger).

Thanks for your help.

Rob
  • 4,123
  • 3
  • 33
  • 53

1 Answers1

12

Here is the manpage for bitcode_strip

remove or leave the bitcode segment in a Mach-O file

bitcode_strip input [ -r | -m | -l ] -o output

What is a Mach-O file?

Mach-O is a file format for executables, object code, shared libraries, dynamically-loaded code, and core dumps

Mach-O also happens to be where iOS and OS X executables are stored, as well as bitcode.

Here is the manpage for xcrun

run or locate development tools

xcrun [-sdk SDK] -find <tool_name>

From my understanding after reading the links you have attached, bitcode is an intermediary step in the compilation process. If you submit your source code to apple by itself, apple will end up having different versions of object code in each app, corresponding to the number of different CPU types that OS X and iOS can run on (over 4 different types). Now, apple can compile your source code most of the way into a minimal form called bitcode, which has no baggage related to which CPU it will be run on.

Most of the way: it does the lexer, parser, semantic analysis and code generation parts of the compiler, which is specific to your source code.

The rest of the way: machine-specific things like optimization, assembling, and linking, which is different on an iPhone compared to a macbook, for example

If you submit the bitcode to the app store, it is much easier to finish compiling it into different final forms for different CPU types. It looks like your problem was that the bitcode in your project ended up being quite a large file (this came from Twilio adding support for bitcode). "Stripping" the bitcode basically removed the bitcode from your project (removes the bitcode segment from your Mach-O file), allowing it to fit within your size constraints. The downside is that apple won't have the bitcode, they'll only have the binary (and will not be able to recompile).

Lets break down the code you linked on github:

source 'https://github.com/twilio/cocoapod-specs'

target 'ObjCVideoQuickstart' do
  pod 'TwilioVideo', '1.0.0-beta14'
end

post_install do |installer|
  # Find bitcode_strip
  bitcode_strip_path = `xcrun -sdk iphoneos --find bitcode_strip`.chop!

  # Find path to TwilioVideo dependency
  path = Dir.pwd
  framework_path = "#{path}/Pods/TwilioVideo/TwilioVideo.framework/TwilioVideo"

  # Strip Bitcode sections from the framework
  strip_command = "#{bitcode_strip_path} #{framework_path} -m -o #{framework_path}" 
  puts "About to strip: #{strip_command}"
  system(strip_command)
end

1.

bitcode_strip_path = `xcrun -sdk iphoneos --find bitcode_strip`.chop!

Locates the bitcode_strip tool in your Xcode installation (read the manpage linked above for xcrun)

2.

framework_path = "#{path}/Pods/TwilioVideo/TwilioVideo.framework/TwilioVideo"

Finds the framework you want to remove the bitcode from

3.

strip_command = "#{bitcode_strip_path} #{framework_path} -m -o #{framework_path}" 
puts "About to strip: #{strip_command}"
system(strip_command)

Creates and executes the command to actually remove the bitcode section from the Mach-O executable. -m is specified for removal (see the linked manpage for bitcode_strip)

please note: using the solution provided by this twilio employee (or other solutions like this) may not be future-proof, as bitcode may become mandatory in the app store

For more information, look into "app thinning"

Noam Hacker
  • 4,671
  • 7
  • 34
  • 55
  • Thanks for the great answer! I'm still a bit confused about one thing: does it mean that if I upload my app without bitcode Apple won't be able to install only the slice that's related to the device's CPU, or are those things not related? – Rob Oct 01 '18 at 13:37
  • @Rob the `Low Level Bits` article leads me to believe that slices for all CPUs are stored in the app store but your device will only install the relevant one. I think apple's goal with bitcode is that they can strip out useless object code before they compile all the app versions themselves in the app store, leading to smaller app sizes. If you upload your app without bitcode, I believe your end users will still only download the relevant version, but it might have extra object code – Noam Hacker Oct 01 '18 at 16:38
  • This is exactly what I was thinking, but then I found [this article on Medium](https://medium.com/@vikaskore/bitcode-slicing-odrs-app-thinning-7c4b294ddec3), and only got more confused... I quote: _Slicing [...] is the process of Apple optimizing your app for a user’s device based on the device’s resolution and architecture. Slicing does not require Bitcode._ So... what to think? – Rob Oct 01 '18 at 17:31
  • @Rob that's a great article. pretty sure slicing would be done by xcode, and all the variants would get sent to the app store. I believe slicing is just default, its what happens when bitcode is not used. the **object code** from all slice variants will be sitting on the user's disk wasting space though. but, with both options, users will only download the relevant app variant and resources. bitcode's improvement is no excess object code when using bitcode, and the ability for apple to recompile for new architectures. when you send bitcode, there is no need for slicing – Noam Hacker Oct 01 '18 at 21:28
  • @Rob [this article](https://www.hedgehoglab.com/blog/about-app-thinning) says that the bitcode approach actually still makes use of slicing for the resources of the app. for example, bitcode gets sent to the app store, but all the images for different screen resolutions do too. none of these _require_ each other, but mixing these together is an effective technique called 'app thinning' – Noam Hacker Oct 02 '18 at 01:35
  • Ok I get it now. Thanks for the explanation! – Rob Oct 03 '18 at 14:06
  • @Rob glad I could help :D – Noam Hacker Oct 03 '18 at 14:09