Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-23853] Hyperloop: iOS - Support embedded binaries

GitHub Issuen/a
TypeNew Feature
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2017-09-18T15:14:49.000+0000
Affected Version/shyperloop 1.2.7
Fix Version/sHyperloop 2.2.0
ComponentsHyperloop, iOS
Labelsbinary, frameworks, hyperloop
ReporterRodolfo Perottoni
AssigneeJan Vennemann
Created2016-08-04T00:22:42.000+0000
Updated2018-01-26T21:26:59.000+0000

Description

Some iOS frameworks require the XCode project to reference the *.framework* file in the "Embedded Binaries" section of the project properties. !Screen Shot 2016-08-04 at 10.19.04 AM.png|thumbnail! [Charts](https://github.com/danielgindi/Charts) is an example.

Attachments

FileDateSize
Screen Shot 2016-08-04 at 10.19.04 AM.png2016-08-04T00:19:28.000+00007941

Comments

  1. Hans Knöchel 2016-08-04

    Not sure what you mean here. Can't you link the local-embedded framework like done with other local frameworks? E.g. by placing it in /src and referencing it in the appc.js.
  2. Rodolfo Perottoni 2016-08-04

    The difference is that everything you put into the "embedded binaries" section in XCode gets packaged into your app's IPA. Some frameworks (like Charts) requires that you reference it both as a "embedded binary" and a "linked framework or library".
  3. Hans Knöchel 2016-08-04

    But if you want it packaged with the app, couldn't you just place it in app/platform/ios? All assets there will be packaged (uncompiled) with the app.
  4. Rodolfo Perottoni 2016-08-04

    I will try it once i get to the office. But i think it won't work - the embedded binaries must be referenced in the XCode project properties in order for Charts to work (according to their documentation).
  5. Rodolfo Perottoni 2016-08-04

    Hey @Hans Knoechel. I've tried doing what you said, but all that happens if you put a file in the *app/platform/ios* folder is that the file gets copied to your XCode project. It doesn't necessarily get references as a "embedded binary". Basically the Charts framework needs 3 important things in order to work: 1) You gotta copy their .xcodeproj inside the project that you want to use it. 2) Somewhere in your code you must have a *@import Charts;* 3) In the project properties you gotta reference the *.framework* file in the embedded binaries. I don't know if it's possible to do any of these steps above with HyperLoop. Can you confirm that ?
  6. Rodolfo Perottoni 2016-08-05

    I've gave up on the Charts Framework and went for Core Plot. Guess what ? Same problem. In order to put it to work i had to... 1) Put CorePlot.framework inside "src" in my project root folder 2) Reference it in my *appc.js* 3) Build the project. All the hyperloop wrappers are created flawlessly! 4) When opening the app i get the same error as i was getting for the Charts framework:
       Dyld Error Message:
         Library not loaded: @rpath/CorePlot.framework/CorePlot
         Referenced from: /Users/USER/Library/Developer/CoreSimulator/Devices/72A6BC5A-112B-4499-909B-4BECED0F1262/data/Containers/Bundle/Application/26BD09A7-17AB-44FD-83B4-C8E0BC3A48DF/loopmodules-coreplot.app/loopmodules-coreplot
         Reason: image not found
       
    5) Opened the titanium generated *.xcodeproj* file. - i was doing the same for *Charts* 6) Dragged the *CorePlot.xcodeproj* inside the project (thus transforming it into an XCode Workspace) - i was doing the same for *Charts* 7) Referenced the *CorePlot.framework* file as a *Embedded Binary* 8) Run the app from XCode -> app opens flawlessly. I'm starting to think that these two frameworks are not the only ones that require you to move their .xcodeproj file inside your project workspace + reference them as an Embedded Binary. It'd be good to investigate a way to do these procedures from inside the titanium SDK / HyperLoop core in case the user wants to.
  7. Rodolfo Perottoni 2016-08-05

    I've just noticed that on the error that i've posted above XCode is searching for the CorePlot framework in the folder */Users/USER/Library*, but this user called "USER" doesn't exist at all. Hmmm..
  8. Hans Knöchel 2016-08-05

    Interesting, interesting. Let me check what the .pbxproj needs to include to add it. After that we can estimate the workload and schedule it. Thanks!
  9. Rodolfo Perottoni 2016-08-11

    Hey Hans. Any thoughts on this?
  10. Adam Paxton 2016-08-22

    I'm also getting the /Users/USER path and Image Not Found error on a different framework [mapbox](https://www.mapbox.com/ios-sdk/)
  11. Rodolfo Perottoni 2016-09-01

    I've noticed that the best frameworks out there require adding the binary file to the "Embedded binaries". This leaves us with no options but to give up on using the top quality frameworks that could really change the game for us. Can we at least have a feedback on when you plan to release this feature?
  12. Hans Knöchel 2016-09-01

    Hey there, moved the ticket to TIMOB and scheduled it for 6.1.0 for now (since 6.0.0 is already completed / code-freezed). Please provide as many information beforehand, e.g.: - Example library that uses embedded libraries - Example code of that library (keep it simple for the test-case) - Attach the generated metabase and a full trace-log of it not being working Thanks!
  13. Rodolfo Perottoni 2016-09-01

    Example libraries that i've came across and that use embedded binaries: - https://github.com/iZettle/sdk-ios - https://www.mapbox.com/ios-sdk/ - https://github.com/danielgindi/Charts - https://github.com/storehouse/Advance Example code / metabase is not necessary, because the app will crash if you use a library without its *.framework* embedded anyways. Using the Charts example: -> import "Charts" on your Podfile -> run the project with this line in any controller:
        var chart = require("Charts/Charts");
        
    It should crash the app when it opens.
  14. Hans Knöchel 2016-09-01

    Well, the above usage is incorrect. I would rather suggest something like var ChartXAxis = require("Charts/ChartXAxis"); since we need to require the class-names. The framework also seems to be written in Swift, so that may cause other problems (not sure).
  15. Rodolfo Perottoni 2016-09-01

    I've just tested it again. Apparently you don't even need to require something in your code. As long as you have the *Charts* pod referenced in your podfile, when you open your app it will crash.
  16. Hans Knöchel 2016-09-01

    Ok thanks, will help to get a reproducible case quickly!
  17. Rodolfo Perottoni 2016-09-01

    Think I've got something... My app is being installed at: */Users/rodolfo/Library/Developer/CoreSimulator/Devices/EAE8D8F1-ABB1-4E33-A166-B153C0BF4172/data/Containers/Bundle/Application/F0170255-0F80-4169-BA04-2CC27DAC5918/loopmodules-charts.app/Frameworks* (Of course this folder structure changes in every computer, but it's just to help you look at the right place). Inside my *.app* there was an empty folder called "Frameworks". I copied the *.framework* file there and the error changed to this:
        Dyld Error Message:
          Library not loaded: @rpath/libswiftCore.dylib
        
    I also have the flag *EMBEDDED_CONTENT_CONTAINS_SWIFT: 'YES'* in my *Appc.js*, but this missing swift lib error keeps showing. So manually copying the Framework to my *.app* seems to do the trick. Now the error is swift related... which i will need some time to discover what is that.
  18. Rodolfo Perottoni 2016-09-01

    By the way, since this is a Pod written in Swift you need to declare "use_frameworks!" in your Podfile.
  19. Hans Knöchel 2016-09-01

    (As a workaround), try to add any other Swift-file in the src/ directory, so Hyperloop manages the Swift-lib. In the final PR, this would need to be detected by the Hyperloop-CLI automatically, based on whether your library has Swift-sources.
  20. Rodolfo Perottoni 2016-09-01

    Tried, but it didn't work...
  21. Hans Knöchel 2016-11-21

    Ok, here are the receipt to realize this (to be implemented):

    We need a new section (e.g. embeddedBinaries) in the appc.js, similar to TIMOB-23854:

        hyperloop: {
            ios: {
                xcodebuild: {
                    embeddedBinaries: [
                        "Charts.framework" // placed in "src/"
                    ]
                }
            }
        }
        

    Hook into the .pbxproj file (with some more entries, but this is the main one):

        /* Begin PBXCopyFilesBuildPhase section */
        		DB67ABFB1DE26E8E00724BDD /* Embed Frameworks */ = {
        			isa = PBXCopyFilesBuildPhase;
        			buildActionMask = 2147483647;
        			dstPath = "";
        			dstSubfolderSpec = 10;
        			files = (
        				DB67ABFA1DE26E8E00724BDD /* Charts.framework in Embed Frameworks */,
        			);
        			name = "Embed Frameworks";
        			runOnlyForDeploymentPostprocessing = 0;
        		};
        /* End PBXCopyFilesBuildPhase section */
        
    After that, we still need to distinguish between System-Frameworks and custom frameworks. The easiest way would probably be to either place custom ones in our src/ directory and assume that if the framework cannot be found there is either a System Framework and can be search in the iOS SDK-directory or it's not valid.
  22. Jan Vennemann 2016-11-29

    For usage with CocoaPods this will be resolved with TIMOB-23570 as we then include a script provided by CocoaPods that integrates the Frameworks in the Xcode project and copies them to the Frameworks folder.
  23. Hans Knöchel 2017-01-02

    Hey guys, quick update here: This is a more general CLI ticket then just Hyperloop. That's why it can be fixed for both Hyperloop and the "old" native modules by using our CLI hook "[ti.dynamiclib](https://gist.github.com/hansemannn/5046fcc9a14cc3d09d0874f964b443aa)". I wrote some more details on how to integrate it as well. This ticket will still automate the whole process, but this hook already allows the integration today. Thx!
  24. Eric Merriman 2017-01-14

    [~hansknoechel] Based on your comment, what would you like me to do with this ticket?
  25. Hans Knöchel 2017-02-03

    [~emerriman] It's scheduled for Hyperloop 2.1.0, where we'll likely refactor the above library to an own node-module which then can be used in both the classic module CLI and the Hyperloop CLI. Until then, Hyperloopers can already use the ti.dynamiclib library in their Hyperloop projects already.
  26. Eric Merriman 2017-02-03

    Thanks [~hansknoechel]
  27. Hans Knöchel 2017-04-26

    I've just put this ticket In Progress. It will likely be resolved together with TIMOB-23570 by allowing dynamic frameworks in both (locally) embedded frameworks and CocoaPods frameworks.
  28. Jan Vennemann 2017-10-19

    [~amukherjee], follow these steps to verify this ticket:

    Create a new app, download the Mapbox SDK from https://www.mapbox.com/install/ios/ and place it under app/platform/ios

    Replace the content of app/controllers/index.js with the following:

        var UIScreen = require('UIKit/UIScreen');
        var UIView = require('UIKit/UIView');
        var CGRectMake = require('CoreGraphics').CGRectMake;
        var CLLocationCoordinate2DMake = require('CoreLocation').CLLocationCoordinate2DMake;
        var MGLMapView = require('Mapbox/MGLMapView');
        var screenRect = CGRectMake(0 , 0, UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height);
        var mapView = MGLMapView.alloc().initWithFrame(screenRect);
        mapView.setCenterCoordinateZoomLevelAnimated(CLLocationCoordinate2DMake(59.31, 18.06), 9, false);
        
        $.index.add(mapView);
        
        $.index.open();
        
    *Expected behavior* The app opens a blank white Mapbox view (this is due to a missing access key). In the lower corner the Mapbox logo and an info icon should be visible, indicating that the Mapbox view successfully opened.
  29. Eric Wieber 2017-10-19

    Verified. Able to build and run apps with embedded binaries

JSON Source