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
[TIMOB-23570] Add support for dynamic Frameworks #159
Conversation
metabase/ios/src/util.cpp
Outdated
filePathAndName = filePathAndName.substr(lastSlashBeforeFramework + 1); | ||
} else { | ||
filePathAndName = replace(CXStringToString(clang_getFileName(file)), ctx->getSDKPath(), ""); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor formatting issue
metabase/ios/lib/metabase.js
Outdated
} | ||
var frameworkName = frameworkNameMatches[1]; | ||
var frameworkHeadersPath = path.join(dynamicFrameworkPath, 'Headers'); | ||
var moduleMapPathAndFilename = path.join(dynamicFrameworkPath, 'Modules', 'module.modulemap'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the modulemap always named module
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to disagree. There are module maps like RobotKit.modulemap
, AWSCore.modulemap
and AWSMobileAnalytics.modulemap
available out there which would not be handled correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, can you give a more specific example? I just tried AWSCore from CocoaPods and the built AWSCore.Framework only includes a module.modulemap
.
cacheTokenData.specs.push(checksumMatches[1]); | ||
checksumMatches = specChecksumRegex.exec(podLockfileContent); | ||
} | ||
var podfileChecksumMatch = podLockfileContent.match(/PODFILE CHECKSUM: (.*)/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this working with CocoaPods 0.39 as well? If not we should officially remove it's support as we work more intensively with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, you are right, a Podfile for <=0.39 will not contain the Podfile checksum. While just testing this i was also running into http://blog.cocoapods.org/Sharding/. Considering this we should definitely drop the support for CocoaPods 0.39. Hyperloop 2.2.0 would be the perfect release for that, hence i created TIMOB-24623 and i'd say we leave this as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feeling bad to do it without a major release-bump, but it would irritate people. So I guess we can make an excuse and remove it in 2.2.0. We deprecated it already right? I know we left a note, but it should definitely show a clear deprecating note by now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we print a warning if a version below 1.0 is used here.
metabase/ios/lib/metabase.js
Outdated
var f = includes[fw] || {}; | ||
extractImplementations(fn, f); | ||
includes[fw] = f; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Obviously no fan of string comparisons, but I'm wondering if there might be a way without it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't know how else to properly determine the framework/library name. The path is always structured something like Headers/<LibraryName>/HeaderName.h
. There can be more subfolders under Headers
so i guess this is the easiest way.
metabase/ios/lib/metabase.js
Outdated
* @param {Object} data The CocoaPods metabase mappings to store | ||
*/ | ||
function writeCocoaPodsMetabaseMappingsToCache(cacheDir, cacheToken, data) { | ||
var cacheFilename = 'metabase-mappings-cocoapods-' + cacheToken + '.json'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may want to leave a note somewhere that this name is used across the project or reference it from a global config file. Not sure what's the best way to deal with hardcoded values here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That cache file is only accessed inside the metabase.js
file so there is no need to make it available globally. Although, for better maintainability i moved this line to a separate function, so the naming can be controlled from a single place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perfect, thanks.
Different question: We enable dynamic frameworks support for Cocoapods. How about non-cocoapods libraries (e.g. local embedded frameworks)? |
The current implementation is not directly tied to CocoaPods so we can reuse that to support local embedded frameworks in TIMOB-23853 as well. |
Could we do both together then? Would just love to get the other ticket "In Progress", so the (pretty high number of) watchers are happy that's something is going on. |
Sure we can do that, the Ticket is marked for 2.2.0 anyway. I just already had the CocoaPods stuff laying around from a previous PoC. |
Yeah sure, 2.1.0 is bundled and out of my head, haha. Great! |
@janvennemann Can you please resolve the merge conflicts and validate the ticket with the latest changes you did? I would like to schedule a 2.2.0 with this one and #189 asap. |
Support Hyperloop usage of frameworks that are recognized by the new framework hook in the SDK. Also refactors a major party of the CocoaPods dyanamic framework support to support additional third-party framework configurations.
metabase/ios/lib/generate/index.js
Outdated
@@ -308,6 +314,33 @@ function generateFromJSON (name, json, state, callback, includes) { | |||
} | |||
|
|||
/** | |||
* Takes a single metadata object and normalized the framework property on that object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
normalizes
metabase/ios/lib/generate/index.js
Outdated
* This normalization will try to associate the path with a virtual third-party | ||
* framework that is configured in the appc.js file, and replace it with the virtual | ||
* framework name. Should the path be unknown we remove the framework property as | ||
* it is a symbol which can not be associated to a specific framework and we can't |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cannot
or can't
@@ -77,8 +77,11 @@ function generate (json, mod, state) { | |||
m.class.obj_class_method.length || | |||
Object.keys(m.class.static_variables).length || | |||
m.class.blocks.length) { | |||
if (mod.filename && mod.filename.indexOf('/') > 0) { | |||
m.import = mod.filename; | |||
if (mod.filename.match(/-Swift\.h$/)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do all Swift frameworks expose their Obj-c header with the "-Swift.h" suffix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, Xcode will automatically generate that header filename using the PRODUCT_MODULE_NAME
build setting and adds -Swift
.
metabase/ios/lib/metabase.js
Outdated
/** | ||
* Creates a MD5 hash from the given string data. | ||
* | ||
* @param {String} data Data the hash will be genreated for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generated
metabase/ios/lib/metabase.js
Outdated
* and their header file. | ||
* | ||
* Frameworks written in Swift are currently only supported if they provide an | ||
* ObjC Interface Header. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interface header
var implementationToHeaderFileMap = includes[frameworkName] || {}; | ||
extractImplementations(headerPathAndFilename, implementationToHeaderFileMap); | ||
includes[frameworkName] = implementationToHeaderFileMap; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are inline functions still a valid procedure in JS? Not really a fan of it.
metabase/ios/lib/metabase.js
Outdated
var objcInterfaceHeaderFilename = objcInterfaceHeaderMatch[1]; | ||
var headerPathAndFilename = path.join(frameworkHeadersPath, objcInterfaceHeaderFilename); | ||
if (!fs.existsSync(headerPathAndFilename)) { | ||
return callback(new Error('Objective-C interface header file for swift based framework ' + frameworkName.green + ' not found at expected path ' + headerPathAndFilename.cyan + '.')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'Objective-C interface header-file for Swift-based framework ' frameworkName.green + ' not found at expected path ' + headerPathAndFilename.cyan + '.'
metabase/ios/lib/metabase.js
Outdated
if (!fs.existsSync(headerPathAndFilename)) { | ||
return callback(new Error('Objective-C interface header file for swift based framework ' + frameworkName.green + ' not found at expected path ' + headerPathAndFilename.cyan + '.')); | ||
} | ||
util.logger.trace('Swift based framework detected, parsing Objective-C interface header ' + objcInterfaceHeaderFilename.cyan); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swift-based
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either use header
or header-file
every time. Above it's header-file
, here it's header
.
metabase/ios/src/def.cpp
Outdated
if (frameworkPosition != std::string::npos) { | ||
size_t slashBeforeFrameworkPosition = filename.find_last_of("/", frameworkPosition); | ||
return filename.substr(slashBeforeFrameworkPosition + 1, frameworkPosition - (slashBeforeFrameworkPosition + 1)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
metabase/ios/src/def.cpp
Outdated
} | ||
kv["framework"] = getFramework(); | ||
kv["thirdparty"] = !getContext()->isSystemLocation(filename); | ||
kv["filename"] = filename; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation
plugins/hyperloop.js
Outdated
@@ -15,53 +15,61 @@ exports.cliVersion = '>=3.2'; | |||
exports.init = init; | |||
|
|||
/** | |||
* Main entry-point for our plugin which looks for the platform specific | |||
* plugin to invoke | |||
* main entry point for our plugin which looks for the platform specific |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Main
plugins/hyperloop.js
Outdated
* main entry point for our plugin which looks for the platform specific | ||
* plugin to invoke. | ||
* | ||
* A priority of 1300 to makes sure the Hyperloop plugin starts only after the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1300 makes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some review comments to be addressed.
de79d64
to
459bec2
Compare
459bec2
to
1add5ef
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CR looks fine now, approved!
JIRA: https://jira.appcelerator.org/browse/TIMOB-23570