{ "id": "164508", "key": "TIMOB-24142", "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": [ { "id": "18154", "name": "Release 6.0.1", "archived": false, "released": true, "releaseDate": "2016-12-21" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2016-12-19T13:19:56.000+0000", "created": "2016-11-12T10:05:30.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "aps", "entitlements", "facebook", "keychain-access", "team-id" ], "versions": [ { "id": "16980", "description": "New V8", "name": "Release 6.0.0", "archived": false, "released": true, "releaseDate": "2016-11-15" }, { "id": "18322", "name": "Release 5.5.1", "archived": false, "released": true, "releaseDate": "2016-09-28" } ], "issuelinks": [ { "id": "53519", "type": { "id": "10000", "name": "Blocks", "inward": "is blocked by", "outward": "blocks" }, "outwardIssue": { "id": "164571", "key": "MOD-2313", "fields": { "summary": "Ti.Facebook: Add CLI-hook to automatically inject capabilities updates", "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" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false } } } }, { "id": "53508", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "163984", "key": "TIMOB-24041", "fields": { "summary": "Include module hooks in packaged zip", "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" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false } } } } ], "assignee": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "updated": "2016-12-19T13:19:59.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": "10206", "name": "iOS", "description": "iOS Platform" }, { "id": "10207", "name": "Tooling" } ], "attachment": [], "flagged": false, "summary": "iOS: Custom Ti.Facebook entitlements-file overrides CLI-generated entitlements", "creator": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "environment": null, "closedSprints": [ { "id": 751, "state": "closed", "name": "2016 Sprint 23 Tooling", "startDate": "2016-11-05T00:40:36.428Z", "endDate": "2016-11-19T01:40:00.000Z", "completeDate": "2016-11-28T03:51:25.291Z", "originBoardId": 199 } ], "comment": { "comments": [ { "id": "400841", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "*Workaround*: Copy the contents of the generated entitlements file in {{build/iphone}} to your own file and add the {{keychain-access-groups}} key to it afterwards. Then place that file in the root of your project as suggested [here|https://github.com/appcelerator-modules/ti.facebook/blob/3feee7d77ed9eef20936d173292c9e21089c1361/apidoc/Facebook.yml#L17-L34].", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-11-12T10:13:39.000+0000", "updated": "2016-11-12T10:13:51.000+0000" }, { "id": "400844", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Ok, so here is my proposal: \r\n\r\nPR (titanium_mobile/master): https://github.com/appcelerator/titanium_mobile/pull/8603\r\nPR (ti.facebook/master): https://github.com/appcelerator-modules/ti.facebook/pull/75\r\n\r\nIt basically checks if we use the ti.facebook iOS module and if so, it injects the {{keychain-access-groups}} key. This key will already be used for device-builds, but different to our push-notifications, we already need the capability in the Simulator when using Ti.Facebook (because Facebook uses the keychain to store private data, probably the access-token). But as we don't have the {{appPrefix}} from the provisioning profile in the Simulator, we cannot grab it from there. -So I added a check for the {{}} that we already use for watchOS-enabled apps. If it's there -> great, use it. If not, throw an error because Ti.Facebook won't work.- I updated the PR to use the {{$(AppIdentifierPrefix)}} flag instead that will take care of the Simulator keychain. Also, I'm wondering why we couldn't use this for device-builds as well - can the team-id from the provisioning be different from what Xcode uses when processing the flag? I don't think so. But anyway, both will work and the above PR has been tested for the following use-cases:\r\n\r\n- Ti.Facebook not included -> Skip\r\n- Ti.Facebook included, but not the iOS one -> Skip\r\n- Ti.Facebook included, run on device -> Proper entitlements generated in {{build/iphone}}\r\n- Ti.Facebook included, run on simulator -> Proper entitlements generated in {{build/iphone}}\r\n- Ti.Facebook included, push used, run on device -> Proper entitlements generated in {{build/iphone}}\r\n- Ti.Facebook included, push used, run on simulator -> Proper entitlements generated in {{build/iphone}}\r\n\r\nCode-style to be discussed, [~cbarber] is the man to check! Backport coming as soon as the master-PR is accepted.\r\n\r\n*EDIT*: And if we accept the PR, we can also remove the manual notes from the Ti.Facebook docs and delelopers will be happy because they don't need to curate multiple entitlements files.\r\n\r\nTest-case:\r\n{code:javascript}\r\nvar fb = require('facebook');\r\nfb.initialize();\r\nfb.permissions = ['email'];\r\n\r\nvar win = Ti.UI.createWindow({\r\n backgroundColor: \"#fff\"\r\n});\r\n\r\nvar btn = Ti.UI.createButton({\r\n title: \"Trigger login\"\r\n});\r\n\r\nfb.addEventListener(\"logout\", function(e) {\r\n Ti.API.info(\"Logged out!\");\r\n Ti.API.info(e);\r\n});\r\n\r\nfb.addEventListener(\"login\", function(e) {\r\n Ti.API.info(\"Logged in!\");\r\n Ti.API.info(e);\r\n\r\n if (e.success) {\r\n alert(\"Logged In!\"); \r\n }\r\n})\r\n\r\nbtn.addEventListener(\"click\", function() {\r\n fb.logout();\r\n fb.authorize();\r\n});\r\n\r\nwin.add(btn);\r\nwin.open();\r\n{code}", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-11-12T13:38:01.000+0000", "updated": "2016-11-12T23:03:55.000+0000" }, { "id": "400933", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "After giving the titanium_mobile PR much consideration, I think that we should NOT accept it. It tightly couples an optional module into the already overly complicated iOS build system.\r\n\r\nInstead, I propose we add a new {{\"build.ios.writeEntitlements\"}} hook to the iOS build in the {{_embedCapabilitiesAndWriteEntitlementsPlist()}} function. This function is called for both the Titanium app's entitlements file and each iOS Extension's entitlements file, so we would need to pass in a flag to indicate which context so that it can create the correct hook name {{\"build.ios.writeEntitlements\"}} or {{\"build.ios.writeExtentionEntitlements\"}}.\r\n\r\nIt was easier for me to just code it then the tell you how to do it. :) PR: https://github.com/appcelerator/titanium_mobile/pull/8606\r\n\r\nThen in the Facebook module, add a {{hooks/facebook.js}} that hooks into the {{\"build.ios.writeEntitlements\"}} event and adds the missing {{keychain-access-groups}}. It would look like:\r\n\r\n{code}\r\n'use strict';\r\n\r\nexports.id = 'com.appcelerator.facebook';\r\n\r\nexports.cliVersion = '>=3.2';\r\n\r\nexports.init = function init(logger, config, cli, appc) {\r\n\tcli.on('build.ios.writeEntitlements', {\r\n\t\tpre: function (data, finished) {\r\n\t\t\tvar applicationIdentifier = '$(AppIdentifierPrefix)' + this.tiapp.id;\r\n\t\t\tvar plist = data.args[0];\r\n\r\n\t\t\tArray.isArray(plist['keychain-access-groups']) || (plist['keychain-access-groups'] = []);\r\n\t\t\tif (!plist['keychain-access-groups'].some(function (id) { return id === applicationIdentifier; })) {\r\n\t\t\t\tplist['keychain-access-groups'].push(applicationIdentifier);\r\n\t\t\t}\r\n\r\n\t\t\tfinished();\r\n\t\t}\r\n\t});\r\n};\r\n{code}\r\n\r\nMuch cleaner integration. I should note that this code has not been tested, so give it a quick test.", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-11-14T23:10:25.000+0000", "updated": "2016-11-14T23:10:25.000+0000" }, { "id": "401102", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "[~cbarber] Will this be ready for 6.0.1? It needs to be well-tested against many use-cases. Thx!", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-11-16T03:22:47.000+0000", "updated": "2016-11-16T03:22:47.000+0000" }, { "id": "401103", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "[~hansknoechel] Well, I wasn't planning on allocating any more time to this ticket. I agree, it needs to be well-tested.", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-11-16T03:25:19.000+0000", "updated": "2016-11-16T03:25:19.000+0000" }, { "id": "401104", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "The problem that I'm having with this is that it needs both module and SDK-updates as well as TIMOB-24041 resolved. So either use the other solution for 6.0.1 and come up with the refactored one in 6.1.0 or finish both tickets in this sprint. More worried about the available resources for this issue, that's why I came up with my workaround.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-11-16T03:27:31.000+0000", "updated": "2016-11-16T03:28:02.000+0000" }, { "id": "401105", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "Well, separate out the module hook into a new MOD ticket. That should take 5 minutes. Then let's get the PR for this ticket tested and merged. That should take an hour. Then lets fix TIMOB-24041, which should take about 2 hours. Then I've already written the hook for the Facebook module, just need to drop that in and test it, then merge and issue a PR for the updated iOS Facebook module. Maybe 2 hours of work. Easy peasy.", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-11-16T03:35:55.000+0000", "updated": "2016-11-16T03:35:55.000+0000" }, { "id": "401361", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Created MOD-2313 for adding the CLI-hook.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-11-17T15:32:53.000+0000", "updated": "2016-11-17T15:32:53.000+0000" }, { "id": "401466", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "I confirmed the new hooks are fired and the entitlements can be manipulated. The new hooks are {{build.ios.writeEntitlements}} and {{build.ios.writeExtensionEntitlements}}.\r\n\r\nTiSDK master PR: https://github.com/appcelerator/titanium_mobile/pull/8606\r\nTiSDK 6_0_X PR: https://github.com/appcelerator/titanium_mobile/pull/8622", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-11-17T19:21:46.000+0000", "updated": "2016-11-17T19:21:46.000+0000" }, { "id": "401546", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "The PR works very well, tested together with MOD-2313 and the hook is called correctly, the capabilities are updated as expected. ", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-11-18T18:03:00.000+0000", "updated": "2016-11-18T18:03:00.000+0000" }, { "id": "402302", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~cbarber], [~hansknoechel], I am seeing some unexpected behavior when building with a custom entitlements file in {{/platform/ios}}.\r\nOn first/clean builds, the custom file looks to be copied to the build folder. On subsequent builds, the entitlements file in the build folder is overwritten with the generated file. I would expect the same file in the build folder on each build, without any modifications to the project. Is this accurate?\r\nTested with SDK 6.0.1.v20161130023500 and Facebook Module 5.2.9", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-12-01T00:24:11.000+0000", "updated": "2016-12-01T00:24:11.000+0000" }, { "id": "402339", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "The issue has been narrowed down to the Module hook, so moving the conversation to that ticket: MOD-2313", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-12-01T14:50:22.000+0000", "updated": "2016-12-01T14:50:22.000+0000" }, { "id": "402453", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "[~ewieber] So, here's the deal. Custom entitlements files MUST be named {{Entitlements.plist}} and it must go in the root of your Titanium app. This custom entitlements file is read in, processed, and written to {{build/iphone/.entitlements}}.\r\n\r\nHowever, this is not what you did. You put a {{.entitlements}} file in the {{platform/ios}} directory. Your custom entitlements file will be copied over the generated {{.entitlements}}.\r\n\r\nWhen a subsequent build occurs, it will generate the {{build/iphone/.entitlements}} file again. However, this time when it copies the {{platform/ios/.entitlements}} file, it will find the entry from the previous build in the manifest and check the timestamps and hash of the {{platform/ios/.entitlements}} against what was copied in the previous build. Since they are the same, the {{platform/ios/.entitlements}} file is NOT copied. The problem is the build has written a newly generated {{.entitlements}} and the entry in the previous build manifest is now stale.\r\n\r\nProbably the easiest thing to do is delete the entry from the previous build manifest when the generated {{.entitlements}} is created. When the iOS build goes to copy {{platform/ios/.entitlements}}, there will be no entry and it will force copy the custom entitlements file.\r\n\r\nThe fix should be done in the {{_embedCapabilitiesAndWriteEntitlementsPlist()}} function, after the {{this.unmarkBuildDirFile(dest);}} call. We need to do something like this amazing and untested code:\r\n\r\n{code}\r\nif (this.previousBuildManifest.files) {\r\n\tvar rel = path.relative(this.buildDir, dest);\r\n\t['ios', 'iphone'].forEach(function (dir) {\r\n\t\tvar file = path.join(this.projectDir, 'platform', dir, rel);\r\n\t\tif (fs.existsSync(path.join(this.projectDir, file))) {\r\n\t\t\tdelete this.previousBuildManifest.files[file];\r\n\t\t}\r\n\t});\r\n}\r\n{code}\r\n\r\nNote that we have to be careful since the {{_embedCapabilitiesAndWriteEntitlementsPlist()}} function is also called for entitlements files from extensions and watch apps, hence the relative path handling.", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-12-02T00:55:33.000+0000", "updated": "2016-12-02T00:55:33.000+0000" }, { "id": "402475", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~cbarber], what you explained makes sense and maybe I need to better clarify the entitlements files we are talking about. There are custom entitlements.plist files and custom .entitlements files at work. We recommend to use the latter in TIMOB-23897 and is what uncovered this issue.\r\nAnyway, can we expect a PR for your fix or would you like to break it off into its own ticket?", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-12-02T17:40:14.000+0000", "updated": "2016-12-02T17:40:14.000+0000" }, { "id": "402477", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "[~ewieber] I'll just reopen this ticket since it's a \"bug\" with the fix for this ticket.", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-12-02T17:47:45.000+0000", "updated": "2016-12-02T17:47:45.000+0000" }, { "id": "402488", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "TiSDK master PR: https://github.com/appcelerator/titanium_mobile/pull/8653\r\nTiSDK 6_0_X PR: https://github.com/appcelerator/titanium_mobile/pull/8654\r\n\r\nTo test:\r\n# Create the {{platform/ios}} directory\r\n# Build an iOS app for simulator {{ti build -p ios --build-only}}\r\n# Copy the {{build/iphone/.entitlements}} to {{platform/ios/.entitlements}}\r\n# Modify the {{platform/ios/.entitlements}} by adding {{foobar}}\r\n# Clean the project {{ti clean}}\r\n# Build the iOS app for simulator {{ti build -p ios --build-only}}\r\n# cat {{build/iphone/.entitlements}} and it should contain the {{foo}} key\r\n# Build the app again {{ti build -p ios --build-only}}\r\n# cat {{build/iphone/.entitlements}} and it should contain the {{foo}} key", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-12-02T19:45:34.000+0000", "updated": "2016-12-02T19:45:34.000+0000" }, { "id": "402490", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Tested with both {{platform/ios}} and {{platform/iphone}}, the custom one is used after this change, so the patch is working.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-12-02T20:21:52.000+0000", "updated": "2016-12-02T20:21:52.000+0000" }, { "id": "402504", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Verified fixed, using:\r\nMacOS 10.12 (16A323)\r\nTi SDK 6.0.1.v20161202124626\r\nAppc NPM 4.2.8\r\nAppc CLI 6.0.0\r\nAlloy 1.9.4\r\nXcode 8.1 (8B62)\r\n\r\nThe correct entitlements are present after building with a custom entitlements.plist, .entitlements, or neither file present in the app. {{keychain-access-groups}} is populated and with the exception of an issue where the key has multiple values (MOD-2313) the file looks correct.", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-12-02T22:19:41.000+0000", "updated": "2016-12-02T22:19:41.000+0000" } ], "maxResults": 18, "total": 18, "startAt": 0 } } }