KISS

Keep It Simple Stupid

IPA export error in Xcode and ruby

| comments

I needed to archive my project and export its .ipa file with Xcode, so I went to “Product” > “Archive”. After building the project a new window opens where you click “Export…”, then select “Development”. And it shows “The data couldn’t be read because it isn’t in the correct format.” error:

"The data couldn’t be read because it isn’t in the correct format." Xcode error

How can it be an incorrect format?! Xcode restarts didn’t help.

I clicked “Show Logs”, a Finder window open with a directory with three log files, and at the end of IDEDistribution.standard.log I’ve found something interesting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2018-04-07 18:00:00 +0000  Running /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool '/var/folders/bs/1b45tmjs7d1bg2mbs4116r000000gn/T/IDEDistributionOptionThinning.GPh' '--json' '/var/folders/bs/1b45tmjs7d1bg2mbs4116r000000gn/T/ipatool-json-filepath-7yrAH5' '--info' '--toolchain' '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr' '--platforms' '/Applications/Xcode.app/Contents/Developer/Platforms'
2018-04-07 18:00:00 +0000  ruby 2.3.3p222 (2016-11-21 revision 56859) [universal.x86_64-darwin17]
2018-04-07 18:00:00 +0000  Ignoring eventmachine-1.0.9.1 because its extensions are not built.  Try: gem pristine eventmachine --version 1.0.9.1
2018-04-07 18:00:00 +0000  /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:1593: warning: assigned but unused variable - minVersion
/Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:1593: warning: assigned but unused variable - sdkVersion
… skipped …
2018-04-07 18:00:00 +0000  /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
2018-04-07 18:00:00 +0000  : incompatible library version - /Users/awesome/.rvm/gems/ruby-2.2.3@project/gems/json-1.8.6/lib/json/ext/parser.bundle (fatal)
  from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
  from /Users/awesome/.rvm/gems/ruby-2.2.3@project/gems/json-1.8.6/lib/json/ext.rb:13:in `<module:Ext>'
  from /Users/awesome/.rvm/gems/ruby-2.2.3@project/gems/json-1.8.6/lib/json/ext.rb:12:in `<module:JSON>'
  from /Users/awesome/.rvm/gems/ruby-2.2.3@project/gems/json-1.8.6/lib/json/ext.rb:9:in `<top (required)>'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
  from /Users/awesome/.rvm/gems/ruby-2.2.3@project/gems/json-1.8.6/lib/json.rb:58:in `<module:JSON>'
  from /Users/awesome/.rvm/gems/ruby-2.2.3@project/gems/json-1.8.6/lib/json.rb:54:in `<top (required)>'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
  from /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool:18:in `<main>'
2018-04-07 18:00:00 +0000  2018-04-07 18:00:00 +0000

2018-04-07 18:00:00 +0000  /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool exited with 1

Surprise surprise, ipatool is a ruby script. So here is the root cause: incompatible library version - /Users/awesome/.rvm/gems/ruby-2.2.3@project/gems/json-1.8.6/lib/json/ext/parser.bundle (fatal) — I have an rvm gemset set as the default ruby version for my main project, and it has a different version of the json gem. I can actually reproduce it by running the command /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool manually.

It seems that the json in system is 2.1.0 (using rvm use system && gem list), and mine is 1.8.6. I tried gem install json -v 2.1.0 inside my gemset, but that didn’t help.

One possible fix is to set back the system ruby as the default one: rvm use system --default, but it’s not convenient.

I’ve compared the environment variables from my regular shell and the one that Xcode launches, and found that Xcode adds its paths to $PATH (e.g., /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin), so I’ve updated my ~/.zshrc to check for that and automagically use the system ruby just for Xcode:

1
2
3
4
5
6
7
export PATH="$PATH:$HOME/.rvm/bin" # Add RVM to PATH for scripting
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

[[ "$APP" = *"/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/"* ]] && {
  echo Xcode detected
  rvm use system
}

Restart Xcode after updating the file. And I was able to export the .ipa file.

Comments