Cordova-plugin-iosrtc: Implement Xcode hook to use the right achitecture automatically on device and archive build

Created on 17 Jul 2020  Â·  31Comments  Â·  Source: cordova-rtc/cordova-plugin-iosrtc

Description

Currently developer need to execute manualy https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/extra/ios_arch.js script to extract achitecture for emulator in order to build on device.

Expected results

In xcode you have to create a new run script in 'Build Phases'

echo "Target architectures: $ARCHS"
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")
FRAMEWORK_TMP_PATH="$FRAMEWORK_EXECUTABLE_PATH-tmp"
# remove simulator's archs if location is not simulator's directory
case "${TARGET_BUILD_DIR}" in
*"iphonesimulator")
    echo "No need to remove archs"
    ;;
*)
    if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_arch "i386") ; then
    lipo -output "$FRAMEWORK_TMP_PATH" -remove "i386" "$FRAMEWORK_EXECUTABLE_PATH"
    echo "i386 architecture removed"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_arch "x86_64") ; then
    lipo -output "$FRAMEWORK_TMP_PATH" -remove "x86_64" "$FRAMEWORK_EXECUTABLE_PATH"
    echo "x86_64 architecture removed"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    ;;
esac
echo "Completed for executable $FRAMEWORK_EXECUTABLE_PATH"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")
done
enhancement help wanted

Most helpful comment

Notice this issue is not supposed to be support for user that have build issue, create separate issue or your message will be hide/delete for out of topic.

All 31 comments

Hello @hthetiot, I have built the functionality of the bash script provided here into the after_prepare hook. It can be used in iosrtc plugin.xml or (in my case) in the app's config.xml. Here is a build log:

[05:33:50]: â–¸ [after_prepare hook] Project root: /Users/ionic/builds/abardik/inremote-redirect
[05:33:50]: â–¸ List WebRTC files...
[05:33:50]: â–¸ -rwxr-xr-x   1 ionic  staff    51M Oct 22 05:32 WebRTC
[05:33:51]: â–¸ Architectures in the fat file: WebRTC are: armv7 x86_64 i386 arm64
[05:33:51]: â–¸ Remove i386...
[05:33:51]: â–¸ Remove x86_64...
[05:33:52]: â–¸ List WebRTC files...
[05:33:52]: â–¸ -rwxr-xr-x   1 ionic  staff    25M Oct 22 05:33 WebRTC
[05:33:52]: â–¸ Architectures in the fat file: WebRTC are: armv7 arm64
[05:33:52]: â–¸ List WebRTC architectures...
[05:33:52]: â–¸ WebRTC: Mach-O universal binary with 2 architectures: [arm_v7:Mach-O dynamically linked shared library arm_v7] [arm64]
[05:33:52]: â–¸ WebRTC (for architecture armv7):  Mach-O dynamically linked shared library arm_v7
[05:33:52]: â–¸ WebRTC (for architecture arm64):  Mach-O 64-bit dynamically linked shared library arm64

But when I try to submit the resulted ipa to App Store, it rejects with the following two errors:

[02:43:20]: [Transporter Error Output]: ERROR ITMS-90087: "Unsupported Architectures. The executable for InRemote.app/Frameworks/WebRTC.framework contains unsupported architectures '[x86_64, i386]'."
[02:43:20]: [Transporter Error Output]: ERROR ITMS-90125: "The binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's linker."
[02:43:20]: Transporter transfer failed.

When I open a resulted ipa I can see WebRTC inside (size 34 468 352, packed size 13 453 361), so it is smaller then the original fat WebRTC (51M), however it is also not 25M as in the build log after the removal of i386 and x86_64. It seems like the script did the job, but something is wrong.

I also tried the ios_arch.js approach with "extract/create/clean", but with the same result. The script is here.

I perform the builds on Ionic AppFlow build service. There is no shell access to Ionic AppFlow or any other cloud build services, so the only way to run pre/post scripts is to inject them as hooks.

The AppFlow has the following environment:

macOS 10.14.6
Xcode 11.5
Cordova CLI 9.0.3
iOS Cordova 6.1.1
Ionic CLI 6.9.2
Node.js 12.17.0
npm 6.14.4
Yarn 1.22.4
CocoaPods 1.7.5

I don't know if I had to open a separate issue since this is related to the "App Store submission problem" described in Building.md and thus to the bash script provided here as well as ios_arch.js. But probably it is because of Ionic AppFlow.

I would appreciate any idea what is wrong. Thank you.

@abardik, I'm struggling with the same exact problem with Ionic AppFlow. Script seems to run (I'm logging out the results), but I'm unable to submit the app via Transporter. I'm getting exactly the same errors as you. Please, pleeease let me know if you find a solution. Btw, are you using the "after_prepare" hook?

This is my script I run:

module.exports = function (context) {

  const fs = require('fs');
  const path = require('path');
  const exec = require('child_process').execSync;

  const PATH = 'plugins/cordova-plugin-iosrtc/extra';

  console.log('### Stripping simulator archs...');
  exec('node ios_arch.js --extract', {cwd: PATH, stdio: 'inherit'});
  exec('node ios_arch.js --device', {cwd: PATH, stdio: 'inherit'});
  exec('node ios_arch.js --clean', {cwd: PATH, stdio: 'inherit'});

  console.log('### Finished stripping simulator archs.');
};

Based on these instructions:

https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/docs/Building.md#strip-simulator-archs-usage

@mvaljento Yes, I use after_prepare. I also tried after_compile and before_deploy, assuming maybe something else rewriting WebRTC binary after the after_prepare hook, but it seems like these two hooks are never fired on Ionic AppFlow. Please let us know if you make it works.

I couldn't may it works, unfortunately. @hthetiot could you please add to 6.x+ the compiled version of libWebRTC without emulator architectures, like it was in 5.x lib/libWebRTC-LATEST-Universal-Release.a, to allow us to build App Store compatible ipa on Ionic AppFlow and similar build services? Thank you in advance.

I couldn't may it works, unfortunately. @hthetiot could you please add to 6.x+ the compiled version of libWebRTC without emulator architectures, like it was in 5.x lib/libWebRTC-LATEST-Universal-Release.a, to allow us to build App Store compatible ipa on Ionic AppFlow and similar build services? Thank you in advance.

No you need to use https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/extra/ios_arch.js to remove the architectures. See https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/docs/Building.md#strip-simulator-archs-usage

It work with ionic on Travis. Regarding external Build Service support thye should have script capability like travis does:

but it seems like these two hooks are never fired on Ionic AppFlow.

That a bug on their side, if hook are not trigger it's their problem not our. Fill an issue on their side.

No you need to use https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/extra/ios_arch.js to remove the architectures. See https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/docs/Building.md#strip-simulator-archs-usage

I tried ios_arch.js, and @mvaljento tried it as well, as he explained above, but with the same result. The script does its job, extracts simulator architectures, but App Store rejects the final ipa with the following errors:

[02:43:20]: [Transporter Error Output]: ERROR ITMS-90087: "Unsupported Architectures. The executable for InRemote.app/Frameworks/WebRTC.framework contains unsupported architectures '[x86_64, i386]'."
[02:43:20]: [Transporter Error Output]: ERROR ITMS-90125: "The binary is invalid. The encryption info in the LC_ENCRYPTION_INFO load command is either missing or invalid, or the binary is already encrypted. This binary does not seem to have been built with Apple's linker."

It work with ionic on Travis. Regarding external Build Service support thye should have script capability like travis does:

Ionic AppFlow has a script capability and runs ios_arch.js as an after_prepare hook.

@hthetiot I tried to remove different archs from libWebRTC in the after_prepare hook, and the script works properly successfully removing and repackaging the library with the differeny architectures. But the resulted ipa always contains the same size (~31MB) WebRTC file. It seems like something overwrites it after the simulator architectures already removed and before the library is copied to the ipa.

@hthetiot I tried to remove different archs from libWebRTC in the after_prepare hook, and the script works properly successfully removing and repackaging the library with the differeny architectures. But the resulted ipa always contains the same size (~31MB) WebRTC file. It seems like something overwrites it after the simulator architectures already removed and before the library is copied to the ipa.

Yes you need to add iOS platform after the architecture triming to update platform/ios content for binaries.

I may improve the script to update the already existing binary.

Yes you need to add iOS platform after the architecture triming to update platform/ios content for binaries.

@hthetiot I tried this since it is obvious from the .travis.yml you provided earlier. But when I added the platform after the triming, the after_prepare hook has fired again and failed because there is nothing to trim already at that moment. I have to improve the script to check the existing archs in the library and avoid the second trimming. I will post the result here.

But this approach has another problem - it increases the build time almost twice (in my case, significantly because of more than 20 plugins included in the project and have to be installed and built twice every time I commit the updates). But for projects with few plugins it's ok, probably.

Also I found another workaround, @mvaljento . After the library is trimmed you can store it (for example, to FTP with curl -T WebRTC ftp://yourserver.com --user ftpuser:ftppassword command added to the hook after the trimming), then fork the iosrtc plugin, commit the stored WebRTC (~25MB) to your fork and then build again, but with after_prepare hook removed from your config.xml. You have to do this (replace the library) just once. After that, you can rebuild your project anytime - the library will be there. If you want to build 7x and 8x you have to do the same for M75 and M84. I understand, this is crazy approach, but it did the job for now, I was able to publish to App Store.

I may improve the script to update the already existing binary.

It would be just great. Thank you.

note: Binaries are available here also https://github.com/cordova-rtc/iosrtc.webRTC.framework

Hi @abardik & @mvaljento
I'm using appflow too and was struggling with this issue too.
I've used the before_plugin_install hook (which is called before each plugin install) and add a condition around @mvaljento script:
<platform name="ios"> <hook type="before_plugin_install" src="cordova_hooks/before_iosrtc_plugin_install.js" /> </platform>

module.exports = function(ctx) {
    if (ctx.opts && ctx.opts.plugin && ctx.opts.plugin.id === 'cordova-plugin-iosrtc') {
        const fs = require('fs');
        const path = require('path');
        const exec = require('child_process').execSync;

        const PATH = 'plugins/cordova-plugin-iosrtc/extra';

        console.log('### cordova-plugin-iosrtc before_plugin_install : Stripping simulator archs...');
        exec('node ios_arch.js --extract', {cwd: PATH, stdio: 'inherit'});
        exec('node ios_arch.js --device', {cwd: PATH, stdio: 'inherit'});
        exec('node ios_arch.js --clean', {cwd: PATH, stdio: 'inherit'});

        console.log('### Finished stripping simulator archs.');
    }
};

With this i was able to build in appflow and submit to app store.

Hope this will help!

@yohan-pannet-bbo Thank you for sharing this. @hthetiot Ionic AppFlow is the only option for former Phonegap Build (discontinued) users to build their projects without a massive refactoring. Maybe it's a good idea to add this solution to https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/docs/Building.md#apple-store-submission
Thank you.

Using VoltBuilder (another PhoneGap Build alternative)... they don't support custom hooks, I believe, unless they're integrated into the plugin. Any chance we could get this hook integrated into the plugin itself?

hi friends, i have the following problem since i update to xcode 12.3

"Building for iOS, but the built-in framework 'WebRTC.framework' was created for iOS + iOS Simulator"

@simmunoz I ran into the same problem yesterday and got it working again by following the steps here: https://github.com/cordova-rtc/cordova-plugin-iosrtc/blob/master/docs/Building.md#strip-simulator-archs-usage

@dgreif

Thanks friend, but now I have the following errors :(

  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginEnumerateDevices.swift
  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginMediaStreamRenderer.swift
  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginRTCAudioController.swift
  • CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler

Captura de Pantalla 2021-01-08 a la(s) 13 22 55

@simmunoz what does it show when you run node ios_arch.js --list?

To be clear, what you should have ran from @dgreif's suggestion is:

node ios_arch.js --extract
node ios_arch.js --device
node ios_arch.js --clean

@simmunoz ¿Qué muestra cuando corres node ios_arch.js --list?

Para ser claros, lo que debería haber corrido de la sugerencia de @dgreif es:

node ios_arch.js --extract
node ios_arch.js --device
node ios_arch.js --clean

node ios_arch.js --list
List WebRTC architectures...
WebRTC: Mach-O universal binary with 2 architectures: [arm_v7:Mach-O dynamically linked shared library arm_v7] [arm64]
WebRTC (for architecture armv7): Mach-O dynamically linked shared library arm_v7
WebRTC (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
List WebRTC files...
-rwxr-xr-x 1 simonmunoz staff 25M Jan 8 09:49 WebRTC
Done! Remember to delete generated files ("WebRTC-*") if needed.

If I followed the steps mentioned, in addition to removing and adding the platform again

@dgreif, please ..

it still does not work despite following the steps

node ios_arch.js --list
List WebRTC architectures...
WebRTC: Mach-O universal binary with 2 architectures: [arm_v7:Mach-O dynamically linked shared library arm_v7] [arm64]
WebRTC (for architecture armv7): Mach-O dynamically linked shared library arm_v7
WebRTC (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64

@simmunoz sorry I can't help more. Those stepped worked for me, but it looks like you are hitting a different issue now.

@dgreif

Thanks friend, but now I have the following errors :(

  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginEnumerateDevices.swift
  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginMediaStreamRenderer.swift
  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginRTCAudioController.swift
  • CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler

Captura de Pantalla 2021-01-08 a la(s) 13 22 55

This does not contains the actual error but the command that have errors, errors details should be below this lines.

Also, try iosRTC-sample app here to validate that your environnement is properly setup https://github.com/cordova-rtc/cordova-plugin-iosrtc-sample

Finally, without the actual errors is difficult to understand what is your issue, you need to provide iOS, Xcode versions (full version name), cordova, etc...

It's most likely the issue is between the chair and the keyboard or you app use conflicts plugin.

Notice this issue is not supposed to be support for user that have build issue, create separate issue or your message will be hide/delete for out of topic.

@dgreif
Thanks friend, but now I have the following errors :(

  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginEnumerateDevices.swift
  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginMediaStreamRenderer.swift
  • CompileSwift normal arm64 /Volumes/Externo/Proyectos/buildingclerk-movil/platforms/ios/BuildingClerk/Plugins/cordova-plugin-iosrtc/PluginRTCAudioController.swift
  • CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler

Captura de Pantalla 2021-01-08 a la(s) 13 22 55

This does not contains the actual error but the command that have errors, errors details should be below this lines.

Also, try iosRTC-sample app here to validate that your environnement is properly setup https://github.com/cordova-rtc/cordova-plugin-iosrtc-sample

Finally, without the actual errors is difficult to understand what is your issue, you need to provide iOS, Xcode versions (full version name), cordova, etc...

It's most likely the issue is between the chair and the keyboard or you app use conflicts plugin.

thanks for your help, but your ego is not an valid answer for me

"thanks for your help, but your ego is not an valid answer for me"

First, you completely out of your mind, if the issue was ego i would not even reply to you.

@simmunoz You did not provided the "actual" error message and you talk to me about ego? If you cannot make the difference between and error command result and and error message, we cannot help you and I suggest you change job.

Your issue is between your chair and the keyboard, since travis (Continuous integration) works as the build for more than 400 developers that use iosRTC.

So next time, create an issue instead of piggy back on a unrelated existing issue and provide proper error and version as i requested you already instead of chosing to talk about ego instead of providing meaningful information.

Next time you get ban, i do not maintain Iosrtc for profit, the least you can do is respect the developer that offered you the software.

@simmunoz is banned for 30 days for disrespectful attitude toward the maintainer and creating noise and complaining instead of making productive comments.

@hthetiot

Where is the respect then? First you tell him that the problem is between the chair and the keyboard and now you ban him because he said that you have responded from your ego. Is it fair that you can insult him for free, if he comes for help?

I think your sense of sanity should be analyzed. Would you tell your mother that she doesn't know how to install an office, that the problem is between the chair and the keyboard, or do you teach her how to do it? Tell me if that is not EGO.

First learn to respect those who ask about errors in your development, giving you feedback and if your own feedback is bad, "saying that the problem is between the chair and the keyboard", then what do you expect from the responses of others, If you want to have a healthy group, you should start with yourself.

Very good that you help people with your plugin, and it is what the user thanked you, but terrible if you do it offending them instead of helping them correctly.

@Hackroro read the message here again: https://github.com/cordova-rtc/cordova-plugin-iosrtc/issues/547#issuecomment-758062149

I did provide information that the actual errors was not provided, i did suggest to try sample app for confirmation of plugins conflicts and environnement.

Having an issue between the chair and the keyboard is common, even for me, this should not be taken as an insult but more that the issue is in your environnement or your side.

I do understand that my reaction can be harsh, but I don't think this person will actually help themselves, so instead of polluting the thread even more and because the person started to make personal comment, he got ban.

If look closely to the rest of the issues, i do not react differently, he got his chance to get help, he wasted it. Properly reporting issue and respecting the people that provide and contribute for free to iosRTC is the most basic rule.

First learn to respect those who ask about errors in your development,

Respect is not due, it's gained.

It's not an "errors in your development" but his development, iosRTC works perfectly for many people including me....

if your own feedback is bad, "saying that the problem is between the chair and the keyboard", then what do you expect from the responses of others, If you want to have a healthy group, you should start with yourself.

I did reply that after the ego comment to show I can also be mean. I don't see where my feedback is "bad" since I did try to provide similar help that solved similar issue.

Very good that you help people with your plugin, and it is what the user thanked you, but terrible if you do it offending them instead of helping them correctly.

Again I think you have not fully read the threads and taking a side without the full context. Since I have not seen you here before I do assume you know the person, and that you are bias.

People like that, are the cancer of open source, you wasting maintain time, think all is due for you for free even if you don't provide properly your problem we supposed to help you all the way.

I'm glad that not all contributors are like this on iosRTC and OSC (open source cancer) are not a majority here, yet.

@Hackroro you get ban also because I don't have time to deal with people that don't contribute in a meaningful way to the project and I here to take side or leave comments that simply don't provide any value to the project.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alaanasreng picture alaanasreng  Â·  7Comments

derMani picture derMani  Â·  9Comments

outEduardoSilva picture outEduardoSilva  Â·  11Comments

hthetiot picture hthetiot  Â·  4Comments

aspdev91 picture aspdev91  Â·  10Comments