{ "id": "167925", "key": "TIMOB-24740", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": { "id": "11", "description": "Is not a bug in our product", "name": "Not Our Bug" }, "resolutiondate": "2017-08-08T08:25:34.000+0000", "created": "2017-05-25T21:47:44.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "Hyperloop", "appcelerator", "ios", "mapbox", "thirdparty" ], "versions": [], "issuelinks": [], "assignee": { "name": "emerriman", "key": "emerriman", "displayName": "Eric Merriman ", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-08-23T18:19:14.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "13715", "name": "Hyperloop", "description": "Hyperloop project" } ], "description": "Hi,\r\nI'm trying to use Hyperloop to integrate the mapbox framework to my app, but it is not working.\r\n\r\nAfter following the appcelerator's guide for include third-party framework to ios, when I run the app on the ios simulator, the app crashes and I got a crash report (see attachments).\r\nstep to reproduce : \r\n-create a new project in appcelerator using the default alloy project with hyperloop enabled.\r\n-download the Mapbox iOS sdk at http://mapbox.s3.amazonaws.com/mapbox-gl-native/ios/builds/mapbox-ios-sdk-3.5.4-dynamic.zip\r\n-Unzip and place the Mapbox.framework file in \"src\" folder in the project's root directory\r\n-I add an appc.js file on the project's root directory with those lines :\r\n{code:java}\r\nmodule.exports = {\r\n\thyperloop: {\r\n\t\tios: {\r\n\t\t\txcodebuild: {\r\n\t\t\t\tflags: {\r\n\t\t\t\t\tFRAMEWORK_SEARCH_PATHS: '../../src',\r\n LD_RUNPATH_SEARCH_PATHS: '@executable_path'\r\n\t\t\t\t},\r\n\t\t\t\tframeworks: [\r\n\t\t\t\t\t'Mapbox'\r\n\t\t\t\t]\r\n\t\t\t},\r\n\t\t\tthirdparty: {\r\n\t\t\t\t'Mapbox': {\r\n\t\t\t\t\tsource: ['src'],\r\n\t\t\t\t\theader: 'src',\r\n\t\t\t\t\tresource: 'src'\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\n{code}\r\n-Add the \"MGLMapboxAccessToken\" key in the tiapp.xml\r\n-Edit the index.js controler :\r\n\r\n{code:java}\r\nfunction doClick(e) {\r\n\talert($.label.text);\r\n}\r\nvar MGLMapView = require('Mapbox/MGLMapView');\r\nvar map = new MGLMapView();\r\n$.index.add(map);\r\n$.index.open();\r\n{code}\r\n-run the app on iOS simulator\r\n", "attachment": [ { "id": "62285", "filename": "mapboxtest_2017-05-26-084428_Julien.crash", "author": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "created": "2017-05-25T21:45:56.000+0000", "size": 16203, "mimeType": "application/octet-stream" } ], "flagged": false, "summary": "iOS - Unable to use Mapbox SDK (third-party framework) with Hyperloop", "creator": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "subtasks": [], "reporter": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "environment": "Appcelerator Studio, build: 4.8.1.201612050850\r\nTitanium Studio Version: 4.8.1.1480394157-7v7d7y9Sfvz-z-wFMBL\r\nTiSDK 6.0.4.GA \r\nHyperloop 2.0.1\r\nXcode Version 8.2.1 (8C1002)\r\nOSX Version 10.11.6 (15G1217)\r\niOS simulator 10.2", "closedSprints": [ { "id": 933, "state": "closed", "name": "2017 Sprint 16 SDK", "startDate": "2017-07-30T16:17:10.306Z", "endDate": "2017-08-13T16:17:00.000Z", "completeDate": "2017-08-13T23:06:34.398Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "421921", "author": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "body": "Hello @emerriman ,\r\n\r\nHave you got some news?\r\n\r\nThanks,", "updateAuthor": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "created": "2017-06-14T06:31:26.000+0000", "updated": "2017-06-14T06:32:09.000+0000" }, { "id": "423303", "author": { "name": "kdclaw3@gmail.com", "key": "kdclaw3@gmail.com", "displayName": "Dee Clawson", "active": true, "timeZone": "America/New_York" }, "body": "Just a general note for who ever is working on this. This problem is because Hyperloop doesn't support embedded binaries. I was able to get Mapbox to work using some modification to ti.dynamiclib....", "updateAuthor": { "name": "kdclaw3@gmail.com", "key": "kdclaw3@gmail.com", "displayName": "Dee Clawson", "active": true, "timeZone": "America/New_York" }, "created": "2017-07-02T21:16:13.000+0000", "updated": "2017-07-02T21:16:13.000+0000" }, { "id": "423305", "author": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "body": "Hello @Dee Clawson\r\nThanks for the reply,\r\n\r\nI already tried this solution but without success, can you post an example please?", "updateAuthor": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "created": "2017-07-03T01:05:50.000+0000", "updated": "2017-07-03T01:07:16.000+0000" }, { "id": "423339", "author": { "name": "kdclaw3@gmail.com", "key": "kdclaw3@gmail.com", "displayName": "Dee Clawson", "active": true, "timeZone": "America/New_York" }, "body": "Hey La Fabrik,\r\n\r\nSorry no, our code contains some trade secrets. When ti.dynamiclib is properly modified it works perfect though, best of luck. \r\n\r\nI would suggest getting Matise's module to work first. https://github.com/MatiseAms/ti-mapbox-gl Once you understand it and how he set up dynamiclib it is pretty easy to get working. ", "updateAuthor": { "name": "kdclaw3@gmail.com", "key": "kdclaw3@gmail.com", "displayName": "Dee Clawson", "active": true, "timeZone": "America/New_York" }, "created": "2017-07-03T15:23:57.000+0000", "updated": "2017-07-03T15:25:27.000+0000" }, { "id": "423414", "author": { "name": "kdclaw3@gmail.com", "key": "kdclaw3@gmail.com", "displayName": "Dee Clawson", "active": true, "timeZone": "America/New_York" }, "body": "Actually here you go: \r\n\r\n\r\n{code:javascript}\r\nmodule.exports = {\r\n\thyperloop: {\r\n\t\tios: {\t\t\r\n\t\t\txcodebuild: {\r\n\t\t\t\tflags: {\r\n\t\t\t\t\tFRAMEWORK_SEARCH_PATHS: '../../src',\r\n\t\t\t\t\tLD_RUNPATH_SEARCH_PATHS: '$(inherited) \"@executable_path/Frameworks\" $(FRAMEWORK_SEARCH_PATHS)'\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tthirdparty: {\r\n\t\t\t\t'Mapbox': {\r\n\t\t\t\t\tsource: ['src'],\r\n\t\t\t\t\theader: 'src',\r\n\t\t\t\t\tresource: 'src'\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n{code}\r\n\r\n\r\n{code:java}\r\nif (!Array.prototype.last) {\r\n Object.defineProperty(Array.prototype, 'last', {\r\n value: function() {\r\n return this[this.length - 1];\r\n }\r\n });\r\n}\r\n\r\nexports.id = 'ti.dynamiclib';\r\nexports.cliVersion = '>=3.2';\r\nexports.init = function (logger, config, cli, appc) {\r\n\tcli.on('build.ios.xcodeproject', {\r\n\t\tpre: function (data) {\r\n\t\t\t\r\n\t\t\t// Replace the following variables with your framework / script:\r\n\t\t\t// ---\r\n\t\t\tvar scriptPath = null; '../../src/Mapbox.framework/strip-frameworks.sh'; //'/strip-frameworks.sh'; // Or set to null if not required\r\n\t\t\tvar frameworkPaths = [\r\n\t\t\t\t'../../src/Mapbox.framework'\r\n\t\t\t];\r\n\t\t\t// ---\r\n\t\t\t\r\n\t\t\tvar builder = this;\r\n\t\t\tvar xcodeProject = data.args[0];\r\n\t\t\tvar xobjs = xcodeProject.hash.project.objects;\r\n\r\n\t\t\tif (typeof builder.generateXcodeUuid !== 'function') {\r\n\t\t\t\tvar uuidIndex = 1;\r\n\t\t\t\tvar uuidRegExp = /^(0{18}\\d{6})$/;\r\n\t\t\t\tvar lpad = appc.string.lpad;\r\n\r\n\t\t\t\tObject.keys(xobjs).forEach(function (section) {\r\n\t\t\t\t\tObject.keys(xobjs[section]).forEach(function (uuid) {\r\n\t\t\t\t\t\tvar m = uuid.match(uuidRegExp);\r\n\t\t\t\t\t\tvar n = m && parseInt(m[1]);\r\n\t\t\t\t\t\tif (n && n > uuidIndex) {\r\n\t\t\t\t\t\t\tuuidIndex = n + 1;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\r\n\t\t\t\tbuilder.generateXcodeUuid = function generateXcodeUuid() {\r\n\t\t\t\t\treturn lpad(uuidIndex++, 24, '0');\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t\taddLibrary(builder, cli, xobjs, frameworkPaths);\r\n\t\t\taddScriptBuildPhase(scriptPath);\r\n\t\t}\r\n\t});\r\n};\r\n\r\nfunction addLibrary(builder, cli, xobjs, frameworkPaths) {\r\n\tif (!frameworkPaths || frameworkPaths.length == 0) {\r\n\t return; // Skip if no frameworks are specified\r\n\t}\r\n\t\r\n\tframeworkPaths.forEach(function (framework_path) {\r\n\t\tvar framework_name = framework_path.split('/').last();\r\n\r\n\t\t// B6CE2C7E1C90C08400B37C55\r\n\t\tvar frameword_uuid = builder.generateXcodeUuid();\r\n\r\n\t\t// B6CE2C7F1C90C08400B37C55\r\n\t\tvar embeddedFrameword_uuid = builder.generateXcodeUuid();\r\n\r\n\t\t// B6CE2C7D1C90C08400B37C55\r\n\t\tvar fileRef_uuid = builder.generateXcodeUuid();\r\n\r\n\t\t// B6CE2C801C90C08400B37C55\r\n\t\tvar embeddedFrameword_copy_uuid = builder.generateXcodeUuid();\r\n\r\n\t\tcreatePBXBuildFile(xobjs, frameword_uuid, fileRef_uuid, embeddedFrameword_uuid, framework_name);\r\n\t\tcreatePBXCopyFilesBuildPhase(xobjs, embeddedFrameword_copy_uuid, embeddedFrameword_uuid, framework_name);\r\n\t\tcreatePBXFileReference(xobjs, fileRef_uuid, framework_path, framework_name);\r\n\t\tcreatePBXFrameworksBuildPhase(xobjs, frameword_uuid, framework_name);\r\n\t\tcreatePBXGroup(xobjs, fileRef_uuid, framework_name);\r\n\t\tcreatePBXNativeTarget(xobjs, embeddedFrameword_copy_uuid);\r\n\t});\r\n}\r\n\r\nfunction addScriptBuildPhase(scriptPath) {\r\n\tif (!scriptPath) return;\r\n\t\r\n\tvar script_uuid = builder.generateXcodeUuid();\r\n\tvar shell_path = '/bin/sh';\r\n\tvar shell_script = 'bash \\\"' + scriptPath + '\\\"';\r\n\r\n\tcreatePBXRunShellScriptBuildPhase(xobjs, script_uuid, shell_path, shell_script);\r\n\tcreatePBXRunScriptNativeTarget(xobjs, script_uuid);\r\n}\r\n\r\nfunction createPBXBuildFile(xobjs, frameword_uuid, fileRef_uuid, embeddedFrameword_uuid, framework_name) {\r\n\r\n\t/**\r\n\t *\t// .framework in Frameworks\r\n\t *\tB6CE2C7E1C90C08400B37C55 = {\r\n\t *\t\tisa = PBXBuildFile;\r\n\t *\t\t// .framework\r\n\t *\t\tfileRef = B6CE2C7D1C90C08400B37C55\r\n\t *\t};\r\n\t */\r\n\txobjs.PBXBuildFile[frameword_uuid] = {\r\n\t\tisa: 'PBXBuildFile',\r\n\t\tfileRef: fileRef_uuid,\r\n\t\tfileRef_comment: framework_name + ' in Frameworks'\r\n\t};\r\n\txobjs.PBXBuildFile[frameword_uuid][frameword_uuid + '_comment'] = framework_name + ' in Frameworks';\r\n\r\n\t/**\r\n\t *\t// .framework in Embed Frameworks\r\n\t *\tB6CE2C7F1C90C08400B37C55 = {\r\n\t *\t\tisa = PBXBuildFile;\r\n\t *\t\t// .framework\r\n\t *\t\tfileRef = B6CE2C7D1C90C08400B37C55\r\n\t *\t\tsettings = {\r\n\t *\t\t\tATTRIBUTES = [CodeSignOnCopy, RemoveHeadersOnCopy]\r\n\t *\t\t}\r\n\t *\t}\r\n\t */\r\n\txobjs.PBXBuildFile[embeddedFrameword_uuid] = {\r\n\t\tisa: 'PBXBuildFile',\r\n\t\tfileRef: fileRef_uuid,\r\n\t\tfileRef_comment: framework_name + ' in Embed Frameworks',\r\n\t\tsettings: {\r\n\t\t\tATTRIBUTES: ['CodeSignOnCopy', 'RemoveHeadersOnCopy']\r\n\t\t}\r\n\t};\r\n\txobjs.PBXBuildFile[embeddedFrameword_uuid][embeddedFrameword_uuid + '_comment'] = 'MyFramework in Embed Frameworks';\r\n\r\n}\r\n\r\nfunction createPBXCopyFilesBuildPhase(xobjs, embeddedFrameword_copy_uuid, embeddedFrameword_uuid, framework_name) {\r\n\r\n\t/**\r\n\t *\tB6CE2C801C90C08400B37C55 = {\r\n\t *\t\tisa = PBXCopyFilesBuildPhase;\r\n\t *\t\tbuildActionMask = 2147483647;\r\n\t *\t\tdstPath = \"\";\r\n\t *\t\tdstSubfolderSpec = 10;\r\n\t *\t\tfiles = (\r\n\t *\t\t\t// .framework in Embed Frameworks\r\n\t *\t\t\tB6CE2C7F1C90C08400B37C55,\r\n\t *\t\t);\r\n\t *\t\tname = \"Embed Frameworks\";\r\n\t *\t\trunOnlyForDeploymentPostprocessing = 0;\r\n\t *\t};\r\n\t */\r\n\txobjs.PBXCopyFilesBuildPhase = xobjs.PBXCopyFilesBuildPhase || {};\r\n\txobjs.PBXCopyFilesBuildPhase[embeddedFrameword_copy_uuid] = {\r\n\t\tisa: 'PBXCopyFilesBuildPhase',\r\n\t\tbuildActionMask: '2147483647',\r\n\t\tdstPath: '\"\"',\r\n\t\tdstSubfolderSpec: '10',\r\n\t\tfiles: [{\r\n\t\t\tvalue: embeddedFrameword_uuid + '',\r\n\t\t\tcomment: framework_name + ' in Embed Frameworks'\r\n\t\t}],\r\n\t\tname: '\"Embed Frameworks\"',\r\n\t\trunOnlyForDeploymentPostprocessing: 0\r\n\t};\r\n}\r\n\r\nfunction createPBXFileReference(xobjs, fileRef_uuid, framework_path, framework_name) {\r\n\t/**\r\n\t *\tB6CE2C7D1C90C08400B37C55 = {\r\n\t *\t\tisa = PBXFileReference;\r\n\t *\t\tlastKnownFileType = wrapper.framework;\r\n\t *\t\tname = .framework;\r\n\t *\t\tpath = ../../modules/iphone/com.janx.wowza/1/platform/.framework;\r\n\t *\t\tsourceTree = \"\";\r\n\t *\t};\r\n\t */\r\n\txobjs.PBXFileReference[fileRef_uuid] = {\r\n\t\tisa: 'PBXFileReference',\r\n\t\tlastKnownFileType: 'wrapper.framework',\r\n\t\tname: framework_name,\r\n\t\tpath: framework_path,\r\n\t\tsourceTree: '\"\"'\r\n\t};\r\n}\r\n\r\nfunction createPBXFrameworksBuildPhase(xobjs, frameword_uuid, framework_name) {\r\n\t/**\r\n\t *\t1D60588F0D05DD3D006BFB54 = {\r\n\t *\t\tisa = PBXFrameworksBuildPhase;\r\n\t *\t\tbuildActionMask = 2147483647;\r\n\t *\t\tfiles = (\r\n\t *\t\t\t// MyFramework in Frameworks\r\n\t *\t\t\tB6CE2C7E1C90C08400B37C55,\r\n\t *\t\t\tmore stuff\r\n\t *\t\t);\r\n\t *\t};\r\n\t */\r\n\tfor (var key in xobjs.PBXFrameworksBuildPhase) {\r\n\t\txobjs.PBXFrameworksBuildPhase[key].files.push({\r\n\t\t\tvalue: frameword_uuid + '',\r\n\t\t\tcomment: framework_name + ' in Frameworks'\r\n\t\t});\r\n\t\treturn;\r\n\t}\r\n}\r\n\r\nfunction createPBXGroup(xobjs, fileRef_uuid, framework_name) {\r\n\tfor (var key in xobjs.PBXGroup) {\r\n\t\tif (xobjs.PBXGroup[key].name == 'Frameworks') {\r\n\t\t\txobjs.PBXGroup[key].children.push({\r\n\t\t\t\tvalue: fileRef_uuid,\r\n\t\t\t\tcomment: framework_name\r\n\t\t\t});\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction createPBXNativeTarget(xobjs, embeddedFrameword_copy_uuid) {\r\n\tfor (var key in xobjs.PBXNativeTarget) {\r\n\t\txobjs.PBXNativeTarget[key].buildPhases.push({\r\n\t\t\tvalue: embeddedFrameword_copy_uuid + '',\r\n\t\t\tcomment: 'Embed Frameworks'\r\n\t\t});\r\n\t\treturn;\r\n\t}\r\n}\r\n\r\nfunction createPBXRunShellScriptBuildPhase(xobjs, script_uuid, shell_path, shell_script){\r\n\txobjs.PBXShellScriptBuildPhase = xobjs.PBXShellScriptBuildPhase || {};\r\n\txobjs.PBXShellScriptBuildPhase[script_uuid] = { \r\n \t\tisa: 'PBXShellScriptBuildPhase', \r\n \t\tbuildActionMask: '2147483647', \r\n \t\tfiles: '(\\n)', \r\n \t\tinputPaths: '(\\n)', \r\n \t\toutputPaths: '(\\n)', \r\n \t\trunOnlyForDeploymentPostprocessing: 0, \r\n \t\tshellPath: shell_path, \r\n \t\tshellScript: JSON.stringify(shell_script) \r\n \t};\r\n}\r\n\r\nfunction createPBXRunScriptNativeTarget(xobjs, script_uuid) {\r\n\tfor (var key in xobjs.PBXNativeTarget) {\r\n\t\txobjs.PBXNativeTarget[key].buildPhases.push({ \r\n \t\tvalue: script_uuid + '', \r\n \t\tcomment: 'Run Script Phase'\r\n \t\t});\r\n\t\treturn;\r\n\t}\r\n}\r\n{code}\r\n", "updateAuthor": { "name": "kdclaw3@gmail.com", "key": "kdclaw3@gmail.com", "displayName": "Dee Clawson", "active": true, "timeZone": "America/New_York" }, "created": "2017-07-03T20:52:57.000+0000", "updated": "2017-07-03T20:52:57.000+0000" }, { "id": "423546", "author": { "name": "kdclaw3@gmail.com", "key": "kdclaw3@gmail.com", "displayName": "Dee Clawson", "active": true, "timeZone": "America/New_York" }, "body": "Hey La Fabrik,\r\n\r\nI did you one better. I have made an example iOS project with it working. \r\n\r\n https://github.com/kdclaw3/hyperloop-mapbox\r\n", "updateAuthor": { "name": "kdclaw3@gmail.com", "key": "kdclaw3@gmail.com", "displayName": "Dee Clawson", "active": true, "timeZone": "America/New_York" }, "created": "2017-07-05T20:51:01.000+0000", "updated": "2017-07-05T20:51:01.000+0000" }, { "id": "423560", "author": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "body": "hi @Dee Clawson,\r\n\r\nOh thank you, I'll try it asap!", "updateAuthor": { "name": "jcanourgues", "key": "jcanourgues", "displayName": "La Fabrik", "active": true, "timeZone": "Pacific/Noumea" }, "created": "2017-07-06T02:37:08.000+0000", "updated": "2017-07-06T02:37:08.000+0000" }, { "id": "426153", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Resolving issue since this was no Titanium related issue. Side-note: Hyperloop 2.2.0 and SDK 6.2.0 will have core-support for dynamic libraries, so hook won't be necessary anymore.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2017-08-08T08:25:34.000+0000", "updated": "2017-08-08T08:25:34.000+0000" }, { "id": "427103", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket with regards to the above observations.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-08-23T18:19:14.000+0000", "updated": "2017-08-23T18:19:14.000+0000" } ], "maxResults": 9, "total": 9, "startAt": 0 } } }