apache/cordova-node-xcode

How to add system frameworks and custom frameworks?

rwillett opened this issue · 8 comments

Hi

I have been trying to use this module to add system and custom frameworks to automate adding a OneSignal Push Notification to our Ionic app.

We have managed to use the code snippet to generate the right NotificationService.h, NotificationService.m and .plist. That works very well indeed.

However we are stymed as we want to add in four system frameworks, UIKit.framework, WebKit.framework, SystemConfiguration.framework and CoreGraphics.framework as well as the OneSignal.framework. This is the last section to automating the whole of our build :)

We cannot see any documentation on how to use xcode.addframework here. We followed the link to the Swve plugins which were useful, we had a look at those and adapted them to work but as far as we can see, they don't add any frameworks.

Is this easy, have we not lookedf somewhere or is adding the frameworks a non-starter with this module.

Thanks for reading.

Rob

I have managed to get most of the frameworks added by using

var frameworksToAdd = [ 'SystemConfiguration.framework' , 'WebKit.framework' , 'UIKit.framework' , 'CoreGraphics.framework'];
            frameworksToAdd.forEach(function(value) {
		// Add the frameworks needed by OneSignal, add them to the existing Frameworks PbxGroup and PBXFrameworksBuildPhase
                var frameworkFile2 = proj.addFramework(value , { target: extTarget.uuid });

                if (frameworkFile2)
                    console.log("Framework " + value + " added");
                else
                    console.log("Framework " + value + " NOT added");
            });

However for some reason the SystemConfiguration.frameworkis not added.

Also we are trying to add a custom framework held in

./platforms/ios/pods/OneSignal/iOS_SDK/OneSignalSDK/Framework/OneSignal.framework

Adding this as either a filename or as the path above doesn't work.

However we are one step further ahead (two steps forward, one step back).

Thanks

Rob

Thanks. Contribution of documentation, and code updates with tests, and testing instructions would be much appreciated. (I also added the bug label since this looks like undocumented and possibly untested functionality.) Unfortunately we have very limited bandwidth to work on developing and documenting this kind of an update right now.

Our development methodology is pretty close to fuzzing code to see what works and what doesn't. I'd love to say we know what we're doing but it's pretty much a few monkeys randomly hitting keys and hoping that something works. We pilfered the SWRVE plugin shamelessly. Thet certainly seem to know what they are doing unlike us ... :)

We have managed to get three system libraries added but for some reason the fourth one, SystemConfiguration.framework fails.

We will keep experimenting to try and understand whats going on. It's only worth us adding docs when we understand it ourselves. We have also posted code on the OneSignal github site to try and stimulate interest and help there.

We have found the line of code that is causing adding in 'SystemConfiguration.framework' to fail. It's been tricky to get debugging in as quite a lot of the cordova project uses this module.

It's a check in pbxProject.prototype.addFramework


pbxProject.prototype.addFramework = function(fpath, opt) {
    var customFramework = opt && opt.customFramework == true;
    var link = !opt || (opt.link == undefined || opt.link);    //defaults to true if not specified
    var embed = opt && opt.embed;                              //defaults to false if not specified

    const logger = log4js.getLogger('pbxproject');
    logger.debug('pbxProject.prototype.addFramework started');

    if (opt) {
      delete opt.embed;
    }

    logger.debug('pbxProject.prototype.addFramework: ' + JSON.stringify(fpath , null , 2));

    var file = new pbxFile(fpath, opt);

    file.uuid = this.generateUuid();
    file.fileRef = this.generateUuid();
    file.target = opt ? opt.target : undefined;

    logger.debug("file = " + JSON.stringify(file , null , 2));

    if (this.hasFile(file.path))
    {
     	logger.debug(file.path);
        logger.debug("this.hasFile(file.path) is true");
        return false;
    }

Now the logging for SystemConfiguration.framework and for WebKit.framework looks pretty much the same, but adding in WebKit.framework works fine and adding in SystemConfiguration.framework fails on this.hasFile(file.path).

The file.path for SystemConfiguration.framework is

pbxproject - file = {
  "basename": "SystemConfiguration.framework",
  "lastKnownFileType": "wrapper.framework",
  "group": "Frameworks",
  "path": "System/Library/Frameworks/SystemConfiguration.framework",
  "sourceTree": "SDKROOT",
  "includeInIndex": 0,
  "uuid": "F5BFFF3294604C05A1209255",
  "fileRef": "FDCEFD97C091433BB09D629D",
  "target": "B2C008E048804AC5B6B2DC70"
}

the file for WebKit.framework is

file = {
  "basename": "WebKit.framework",
  "lastKnownFileType": "wrapper.framework",
  "group": "Frameworks",
  "path": "System/Library/Frameworks/WebKit.framework",
  "sourceTree": "SDKROOT",
  "includeInIndex": 0,
  "uuid": "9D40A0F1CC7B47D0A3601D0D",
  "fileRef": "498C6B9A40824CAAAD825859",
  "target": "B2C008E048804AC5B6B2DC70"
}

We also can't work out what this.hasFile(file.path) is actually testing. All our searchs show HasFile is used in uploading, yet the node xcode module is doing a constant check through just about every function, so it's not a carelessly placed line (and so not a bug).

Any help or ideas welcomed.

Rob

We've worked out what hasFile is. Didn;t realise it was declared in same file :(

We have also managed to get the SystemConfiguration.framework installed. We think there is a conflict between this node module and how it checks to see what frameworks are available.

We have not managed to get the OneSignal.framework installed, though it's not for lack of trying.

We think its due to a Framework Search Path not being set correctly for the framework but we cannot work out how to resolve this. There is zero documentation as far as we can see on how to do this. We keep looking for code examples but it's not easy.

If anybody understands how to easily add a framework search then please let us know.

Thanks

Rob

Hello!

I am building an automated script to create the iOS build of my project containing OneSignal too.

I've used the following code

proj.addFramework('./documentation/OneSingal.framework',{customFramework: true });

and i got to get it added in the project, however it does not have the briefcase icon, but a white unknown icon.

Unfortunately the build fails if i run it with this setup, telling me it can't find said framework. My OneSignal.framework is located at Ionic-Project/documentation/OneSignal.framework . The error says that it hasn't found the framework at -F/documentation . And I am pretty confused about that -F as I don't really understand where it searched for it.

We never got this to work.

We managed to add other system frameworks, UIKit.framework, WebKit.framework, CoreGraphics.framework, but not SystemConfiguration.framework.

We got SystemConfiguration.framework in by hacking the Xcode node module because for some reason it doesn't add it.

We never got OneSignal.framework to add correctly such that it presented the toolbox icon in Xcode. it only ever presented the brick icon. Also you have a spelling mistake in your code fragment. We got it to compile sometimes but there were so many problems, we gave up.

Without documentation on the pbxproj file format and how the xcode function calls are made and what they do, it's a very difficult task. We were trying to work out API calls and the nightmare that is the pbxproj file format.

We have given up for the moment as the time needed far outweighs the benefit for us. We're happy to help add to the docs as giveback, but at the moment we'd have to start and we simply do not know enough.

Rob