NodObjC
The NodeJS ⇆ Objective-C Bridge
Import
Logic for importing a Framework into the node process.
"Importing" a framework is a multi-step process:
resolve()
the absolute path of the given framework name.- Load the framework's binary
dylib
file into the process. - Usually locate the
BridgeSupport
files for the framework and process. - Define any new class getters for newly loaded Objective-C classes.
importFramework()
Accepts a single framework name and imports it into the current node process.
framework
may be a relative (singular) framework name, or a path (relative or
absolute) to a Framework directory.
$.NSObject // undefined
$.import('Foundation')
$.NSObject // [Class: NSObject]
function importFramework (framework, skip) {
debug('importing framework:', framework, skip)
framework = exports.resolve(framework)
var shortName = basename(framework, SUFFIX)
// Check if the framework has already been loaded
var fw = cache[shortName]
if (fw) {
debug('skipping framework because already loaded:', framework)
return
}
// Load the main framework binary file
var frameworkPath = join(framework, shortName)
, lib = core.dlopen(frameworkPath)
fw = {
lib: lib
, name: shortName
, basePath: framework
, binaryPath: frameworkPath
}
// cache before loading bridgesupport files
cache[shortName] = fw
// Parse the BridgeSupport file and inline dylib, for the C functions, enums,
// and other symbols not introspectable at runtime.
bridgesupport(fw)
// Iterate through the loaded classes list and define "setup getters" for them.
if (!skip) {
var classes = core.getClassList()
debug('loading ObjC Classes:', classes.length)
classes.forEach(function (c) {
if (c in _global) return
_global.__defineGetter__(c, function () {
var clazz = _class.getClass(c)
delete _global[c]
return _global[c] = clazz
})
})
}
debug('finished importing framework:', shortName)
}
resolve()
Accepts a single framework name and resolves it into an absolute path to the base directory of the framework.
In most cases, you will not need to use this function in your code.
$.resolve('Foundation')
// '/System/Library/Frameworks/Foundation.framework'
function resolve (framework) {
debug('resolving framework name or path:', framework)
// strip off a trailing slash if present
if (framework[framework.length-1] == '/') {
framework = framework.slice(0, framework.length-1)
debug('stripped trailing slash:', framework)
}
// already absolute, return as-is
if (~framework.indexOf('/')) return framework
var i = 0
, l = exports.PATH.length
, rtn = null
for (; i<l; i++) {
rtn = join(exports.PATH[i], framework + SUFFIX)
if (exists(rtn)) return rtn
}
throw new Error('Could not resolve framework: ' + framework)
}