Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load Calabash dylibs in Debug configuration at runtime #17

Merged
merged 13 commits into from
Mar 17, 2015

Conversation

jmoody
Copy link
Contributor

@jmoody jmoody commented Mar 13, 2015

Motivation

This PR demonstrates how to load the Calabash dylibs into your app at runtime.

The Calabash dylibs are added to the app bundle using a Run Script Build Phase. The dylibs are only installed for builds using the Debug and the code that loads the dylibs will only be compiled in when the LOAD_CALABASH_DYLIB pre-processor macro is defined. This means your production app will not contain any Calabash related code.

This is an alternative to creating a separate -cal target and linking it with the calabash.framework.

Works on the XTC.

Try it out.

$ git clone git@git@github.com:calabash/ios-smoke-test-app.git
$ cd ios-smoke-test-app/CalSmokeApp
$ bundle
$ bundle exec calabash-ios sim reset # clean the simulator of all targets (optional)
$ make app-dylib
$ export APP="${PWD}/CalSmoke.app"
$ bundle exec cucumber

Updating to the latest Calabash version.

1. # Update your Gemfile.
2. $ bundle update
3. $ cp `bundle show calabash-cucumber`/dylibs/*.dylib ./
4. $ bundle exec calabash-ios sim reset

Implementing this in your own project.

1. Add the dylibs to your project.

$ cd /path/to/your/project  # The directory where your .xcodeproj is.
$ bundle update
$ cp `bundle show calabash-cucumber`/dylibs/*.dylib ./
$ tree -L 1                 # tree can be installed with homebrew
.
├── Gemfile
├── Gemfile.lock
├── chou.xcodeproj
├── install-test-binaries.rb
├── libCalabashDyn.dylib
├── libCalabashDynSim.dylib

2015-03-13_18-02-37

2. Add a Run Script Build Phase in Xcode

2015-03-13_22-55-39

3. Create the Install Script

$ mkdir -p script/xcode-build-phase
$ touch script/xcode-build-phase/add-calabash-dylibs-to-bundle.sh
$ chmod +x script/xcode-build-phase/add-calabash-dylibs-to-bundle.sh

Create the script in your favorite editor.

#!/usr/bin/env bash

# If you see an error like this:
#
# iPhone Developer: ambiguous (matches "iPhone Developer: Person A (2<snip>Q)"
#                                  and "iPhone Developer: Person B (8<snip>F)"
# in /Users/<snip>/Library/Keychains/login.keychain)
#
# Uncomment this line and update it with the correct credentials.
# CODE_SIGN_IDENTITY="iPhone Developer: Person B (8<snip>F)"

set -e

if [ "${CONFIGURATION}" = "Debug" ]; then
  cp "${SRCROOT}/libCalabashDyn.dylib" "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/libCalabashDyn.dylib"
  cp "${SRCROOT}/libCalabashDynSim.dylib" "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/libCalabashDynSim.dylib"
  if [ -n "${CODE_SIGN_IDENTITY}" ]; then
    xcrun codesign -fs "${CODE_SIGN_IDENTITY}" "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/libCalabashDyn.dylib"
  fi
fi

4. Add LOAD_CALABASH_DYLIB Preprocessor Macro

2015-03-13_18-43-08

5. Add Dylib Loading Code to the App Delegate.

...

#if LOAD_CALABASH_DYLIB
#import <dlfcn.h>
#endif

...

@implementation XamAppDelegate

#if LOAD_CALABASH_DYLIB
- (void) loadCalabashDylib {
  NSBundle *bundle = [NSBundle mainBundle];
  NSString *dylibPath;
#if TARGET_IPHONE_SIMULATOR
  dylibPath = [bundle pathForResource:@"libCalabashDynSim" ofType:@"dylib"];
#else
  dylibPath = [bundle pathForResource:@"libCalabashDyn" ofType:@"dylib"];
#endif

  NSLog(@"Attempting to load Calabash dylib: '%@'", dylibPath);
  void *dylib = NULL;
  dylib = dlopen([dylibPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_NOW);

  if (dylib == NULL) {
    char *error = dlerror();
    NSString *message = @"Could not load the Calabash dylib.";
    NSLog(@"%@: %s", message, error);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Calabash"
                                                    message:message
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
  }
}
#endif

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

< snip >

#if LOAD_CALABASH_DYLIB
  [self loadCalabashDylib];
#endif

  return YES;
}

jmoody added a commit that referenced this pull request Mar 17, 2015
…n-app

When Xcode build configuration Debug, load dylibs into the non-calabash target.
@jmoody jmoody merged commit 31b3f33 into master Mar 17, 2015
@jmoody jmoody deleted the feature/load-dylibs-into-production-app branch March 17, 2015 09:03
@jmoody jmoody changed the title When Xcode build configuration Debug, load dylibs into the non-calabash target. Load Calabash dylibs in Debug configuration at runtime Apr 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant