{ "id": "133217", "key": "TIMOB-17335", "fields": { "issuetype": { "id": "6", "description": "gh.issue.epic.desc", "name": "Epic", "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": "17707", "name": "Release 5.3.0", "archived": false, "released": true, "releaseDate": "2016-06-04" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2016-03-28T14:48:33.000+0000", "created": "2014-07-15T21:11:33.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [ "ios8", "notable", "roadmap" ], "versions": [], "issuelinks": [ { "id": "39846", "type": { "id": "10122", "name": "Gantt: start-finish", "inward": "is triggered by", "outward": "is triggering" }, "outwardIssue": { "id": "134642", "key": "TIDOC-1836", "fields": { "summary": "iOS 8 Share Extensions", "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": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } }, { "id": "51567", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "159963", "key": "TIMOB-23303", "fields": { "summary": "iOS: Today extension doesn't show any content", "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": "Critical", "id": "1" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "43054", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "139983", "key": "TIMOB-18052", "fields": { "summary": "iOS: Support WatchKit", "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": "6", "description": "gh.issue.epic.desc", "name": "Epic", "subtask": false } } } } ], "assignee": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "updated": "2016-05-23T21:47:28.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" } ], "description": "iOS 8 allows developers to add extensions to the Share infrastructure.", "attachment": [], "flagged": false, "summary": "iOS8: Add support for Share Extensions", "creator": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "closedSprints": [ { "id": 615, "state": "closed", "name": "2016 Sprint 07 Tooling", "startDate": "2016-03-26T00:40:48.770Z", "endDate": "2016-04-09T00:40:00.000Z", "completeDate": "2016-04-11T04:48:57.781Z", "originBoardId": 121 } ], "comment": { "comments": [ { "id": "319954", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "body": "We're going to put this on hold for now. Not sure how this can be implemented in Titanium at this time. The way to build Extensions, to make a long story short, is by creating a new target in an Xcode project and then subclassing some predefined classes.", "updateAuthor": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-08-22T18:24:38.000+0000", "updated": "2014-08-22T18:24:38.000+0000" }, { "id": "322744", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Since the WatchKit will probably work in a similar way (set of API's plus new target) maybe it's good to start investigating [App Extensions|https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/] and the extension point *Today* in particular so that when WatchKit is published we may have tackled some of the challenges?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2014-09-10T07:34:23.000+0000", "updated": "2014-09-10T07:34:23.000+0000" }, { "id": "322805", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I'm guessing that you would create a set of files in your application, perhaps in a folder (perhaps that's in a specially-named \"extensions\" folder). These would implement certain classes as required. When performing the build, the CLI would then know how to generate the proper Xcode targets for this.\r\n\r\nThoughts?", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-09-10T16:37:50.000+0000", "updated": "2014-09-10T16:37:50.000+0000" }, { "id": "323894", "author": { "name": "wood1k", "key": "wood1k", "displayName": "Alexey Chulochnikov", "active": true, "timeZone": "Europe/Helsinki" }, "body": "+1 to start thinking about it right now", "updateAuthor": { "name": "wood1k", "key": "wood1k", "displayName": "Alexey Chulochnikov", "active": true, "timeZone": "Europe/Helsinki" }, "created": "2014-09-16T06:21:47.000+0000", "updated": "2014-09-16T06:21:47.000+0000" }, { "id": "324542", "author": { "name": "pilo", "key": "pilo", "displayName": "erez pilosof", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "this is important !! any hack around it for now ?", "updateAuthor": { "name": "pilo", "key": "pilo", "displayName": "erez pilosof", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2014-09-18T17:55:43.000+0000", "updated": "2014-09-18T17:55:43.000+0000" }, { "id": "328543", "author": { "name": "Spaceghost", "key": "spaceghost", "displayName": "John McMahon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "First of all, this is going to be a huge limitation if appcelerator cannot implement because of the major user engagement from these widgets. It enables uploads right from iPhoto app or other \"file association\" ios behavior... Former plist document handling zone.... Anyone needing this really needs it.\r\n\r\nSo I cracked open a generated titanium output Xcode project in Xcode. I inserted a new \"share extension\" in the app targets. I was then able to write some bit of swift code and save and compile it. So flawlessly does the sharing work I cannot do without this.\r\n\r\nOf course the Xcode file is now been manually edited and it will be overwritten. Furthermore, enabling swift broke some older titanium code, and the original titanium project no longer ran from Xcode.\r\n\r\nConclusion: this should be a high priority because demand for this functionality is already high, note the mass of non titanium apps available already that save email attachments etc.\r\n\r\nPlease do implement this Xcode target type ... Titanium already handles ios targets for iPad and iPhone, adding the extension should not be too hard.", "updateAuthor": { "name": "Spaceghost", "key": "spaceghost", "displayName": "John McMahon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-19T05:40:51.000+0000", "updated": "2014-10-19T05:42:26.000+0000" }, { "id": "328639", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~Spaceghost] Thank you for your input. I think there are two pieces here. \r\n\r\n# As you mention, it should be relatively trivial for us to allow packaging a native extension a developer has implemented.\r\n# The second (more challenging aspect) is how should a developer indicate that they wished to create a native extension in a Titanium Project. I'm assuming you'd either create a separate project, or indicate that a subset of your files was used for the share extension.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-20T19:09:41.000+0000", "updated": "2014-10-20T19:09:41.000+0000" }, { "id": "328640", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "I would keep it in the same project. Maybe a dedicated folder under Resources?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2014-10-20T19:20:41.000+0000", "updated": "2014-10-20T19:20:41.000+0000" }, { "id": "328642", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "One file per extension? One sub-folder per extension? Then the question of how you do it via Alloy.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-20T19:22:38.000+0000", "updated": "2014-10-20T19:22:38.000+0000" }, { "id": "328655", "author": { "name": "rblalock", "key": "rblalock", "displayName": "Rick Blalock", "active": false, "timeZone": "America/Havana" }, "body": "/platform/ios/extensions/", "updateAuthor": { "name": "rblalock", "key": "rblalock", "displayName": "Rick Blalock", "active": false, "timeZone": "America/Havana" }, "created": "2014-10-20T20:15:51.000+0000", "updated": "2014-10-20T20:15:51.000+0000" }, { "id": "328660", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "I don't have enough insight in how extenions work to say how I'd like to have it structured. Is it a single view/controller? Is it like how you do a service?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2014-10-20T20:28:32.000+0000", "updated": "2014-10-20T20:28:32.000+0000" }, { "id": "328666", "author": { "name": "underlabs", "key": "underlabs", "displayName": "Joseph Sachs", "active": true, "timeZone": "America/Montreal" }, "body": "Looking at the doc: https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/NotificationCenter.html#//apple_ref/doc/uid/TP40014214-CH11-SW1\r\n\r\nI think it would be ideal to have: Today / Share / Action/etc; Extensions to be part of the App (not a separate project).", "updateAuthor": { "name": "underlabs", "key": "underlabs", "displayName": "Joseph Sachs", "active": true, "timeZone": "America/Montreal" }, "created": "2014-10-20T20:46:18.000+0000", "updated": "2014-10-21T12:29:03.000+0000" }, { "id": "328674", "author": { "name": "rblalock", "key": "rblalock", "displayName": "Rick Blalock", "active": false, "timeZone": "America/Havana" }, "body": "I think first priority is making extensions \"possible\", even if its a native extension. Then second step is figuring out if its feasible to run an extension via the JS runtime...so probably shouldn't be worried about auto-layout for the first priority since you'd have to build the extension in native code anyway.\r\n\r\n", "updateAuthor": { "name": "rblalock", "key": "rblalock", "displayName": "Rick Blalock", "active": false, "timeZone": "America/Havana" }, "created": "2014-10-20T21:03:57.000+0000", "updated": "2014-10-20T21:03:57.000+0000" }, { "id": "328681", "author": { "name": "Spaceghost", "key": "spaceghost", "displayName": "John McMahon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Agree with Rick, I'm happy with a workaround, even just a clean way to inject a small bit of swift code into the output Xcode file pre-compile somehow, then CLI can do its thing.\r\n\r\nAFAIK, to deploy to the Apple AppStore, the extension *must* be in the Xcode project and the same app as the \"parent\" application. It is after all an \"app extension\" and logically Apple do not intend it to be treated as a separate entity or independent build-able target.\r\n\r\nI'm assuming to build for iTunes deployment, these changes would have to be made by Titanium before signing the upload package.\r\n\r\nThat said, I did make an extension work using my Titanium output Xcode project and creating a swift app extension. Well the app extension worked, but using swift broke Appcelerator libraries must be compatibility issues there as well.", "updateAuthor": { "name": "Spaceghost", "key": "spaceghost", "displayName": "John McMahon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-20T21:16:25.000+0000", "updated": "2014-10-20T21:19:03.000+0000" }, { "id": "328702", "author": { "name": "Spaceghost", "key": "spaceghost", "displayName": "John McMahon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hi Team,\r\n\r\nI wish i screenshotted my Xcode project it looked very simple to implement. Just a few files were created in a folder and a new target in the Xcode project root.\r\n\r\nSo from the Titanium perspective this would be like having an extra checkbox for iOS Targets\r\n [x] iPhone\r\n [x] Contains iOS extension\r\n\r\nJust take any Xcode project output from Titanium and open in Xcode6.\r\n\r\nThen follow the instructions here and create a swift widget:\r\nhttp://www.glimsoft.com/06/28/ios-8-today-extension-tutorial/\r\n\r\nI needed a \"Share\" widget to access photos and webpages and email attachments etc.\r\n\r\nI was able to use my Titanium project as the \"Base\" which showed clearly the file layout.\r\n\r\nYou may have some compile issues perhaps if you have certain Ti.xx modules but I was able to just comment out the offending lines and continue to build my extension (While of course knowing my App would be rendrered useless so I did not worry about modding ti code.", "updateAuthor": { "name": "Spaceghost", "key": "spaceghost", "displayName": "John McMahon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-10-20T22:07:50.000+0000", "updated": "2014-10-20T22:07:50.000+0000" }, { "id": "328766", "author": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "updateAuthor": { "name": "cbowley", "key": "cbowley", "displayName": "Chris Bowley", "active": true, "timeZone": "Europe/London" }, "created": "2014-10-21T08:20:11.000+0000", "updated": "2014-10-21T08:20:11.000+0000" }, { "id": "363573", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~cbarber], as discussed about in ios extensions. Considering this particular share extension has so many listeners, we may consider implementing it as a template flag that we discussed before.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-09-11T02:37:17.000+0000", "updated": "2015-09-11T02:37:17.000+0000" }, { "id": "366102", "author": { "name": "pilo", "key": "pilo", "displayName": "erez pilosof", "active": true, "timeZone": "Asia/Jerusalem" }, "body": "any news on this one... what's the ETA ?", "updateAuthor": { "name": "pilo", "key": "pilo", "displayName": "erez pilosof", "active": true, "timeZone": "Asia/Jerusalem" }, "created": "2015-10-07T15:59:05.000+0000", "updated": "2015-10-07T15:59:05.000+0000" }, { "id": "366106", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "[~pilo] Share extensions should work. Creating new share extensions are currently not supported by the {{appc new}} or {{ti create}} commands. You have to manually create the Xcode project, add the share extension as a target, then add the extension and target to the tiapp.xml. I can't find the docs on how to do this. You can find an tiapp.xml example for a WatchKit extension here: https://docs.appcelerator.com/platform/latest/#!/guide/Integrate_a_WatchKit_App_Built_in_Xcode. You simply need to ignore the WatchKit app target and only add the share extension target.", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2015-10-07T16:23:29.000+0000", "updated": "2015-10-07T16:23:29.000+0000" }, { "id": "373204", "author": { "name": "ivan.skugor", "key": "ivan.skugor", "displayName": "Ivan Skugor", "active": true, "timeZone": "Europe/Amsterdam" }, "updateAuthor": { "name": "ivan.skugor", "key": "ivan.skugor", "displayName": "Ivan Skugor", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-12-17T11:16:32.000+0000", "updated": "2015-12-17T11:16:32.000+0000" }, { "id": "374537", "author": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "body": "I've done some further investigation on this. We had a project with Extensions that work with tisdk 3.2 beta back when tooling was first working on extensions. We have migrated to Ti 5.0.2 and 5.1.2 and the extensions are no longer included in the IPA. They show in the generated xcode project, but do not get included into the build.\r\n\r\nI've published a minimum viable version of the app to github at https://github.com/jeffbonnes/appc-doc-provider-example.\r\n\r\nThe branch that works using TiSDK 3.2 Beta is at https://github.com/jeffbonnes/appc-doc-provider-example/tree/ti-sdk-2.5.2beta.\r\n\r\nThe upgraded version that doesn't work is on branch https://github.com/jeffbonnes/appc-doc-provider-example/tree/ti-sdk-5.x.\r\n\r\nA summary of the changes made to tiapp.xml for V5 of the SDK is at https://github.com/jeffbonnes/appc-doc-provider-example/commit/7be8db3b8ee0a2fa4bdc25a7913966e300d0bad1.\r\n\r\nInteresting, the expected appex files that should be included in the IPA are in the build/Products directory, but not in the IPA. I'm happy to provide any additional information, but right now, Extensions are not working on iOS.\r\n", "updateAuthor": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "created": "2016-01-14T06:20:59.000+0000", "updated": "2016-01-14T06:20:59.000+0000" }, { "id": "374539", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "We focused testing on watch extensions, though any extension should work. FWIW, we have limited support for non-watch extensions and app groups. Regardless, it's possible that share extensions require a different build phase or dependency wire up in the Xcode project. The best place to start is to build the Titanium app with your share extension and open the generated Xcode project in the {{build/iphone}} directory. Next create a new native iOS app with a share extension. With both Xcode projects open, compare the build phases, dependencies, and capabilities. Is there any discrepancies? If so, what?", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-01-14T06:33:17.000+0000", "updated": "2016-01-14T06:33:17.000+0000" }, { "id": "374766", "author": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "body": "I had a look at the generated xcode project compared to a standard xcode project with extensions and can see the issue. All the code for the extensions are in the generated xcodeproject, but they are not listed in the 'Embedded Binaries' section of the General tab of the main target.\r\n\r\nWhen I added all the extensions in the Embedded Binaries section and ran on device from xcode, it worked as expected.", "updateAuthor": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "created": "2016-01-18T02:32:54.000+0000", "updated": "2016-01-18T02:32:54.000+0000" }, { "id": "377633", "author": { "name": "hambast", "key": "hambast", "displayName": "Neil H", "active": true, "timeZone": "Europe/London" }, "body": "Is there a workaround to get share extension bundled again in the meantime? Even if it involves manual intervention with xcode - got an app partly broken since updating SDK.", "updateAuthor": { "name": "hambast", "key": "hambast", "displayName": "Neil H", "active": true, "timeZone": "Europe/London" }, "created": "2016-02-23T10:35:36.000+0000", "updated": "2016-02-23T10:35:36.000+0000" }, { "id": "380049", "author": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "body": "I've gotten this to work with a simple Document Provider extension by modifying the /iphone/cli/commands/_build.js script in the Titanium SDK. I tested with version 5.2.0.GA but this should also work with the most current code on the 5_2_X branch on GitHub.\r\n\r\nAround line 3131 of iphone/cli/commands/_build.js reads:\r\n{code:javascript}\r\nif (targetInfo.isWatchAppV1Extension ) {\r\n\taddEmbedBuildPhase.call(this, 'Embed App Extensions', null, 13 /* type \"plugin\" */);\r\n} else if (targetInfo.isWatchAppV2orNewer) {\r\n\taddEmbedBuildPhase.call(this, 'Embed Watch Content', '$(CONTENTS_FOLDER_PATH)/Watch', 16 /* type \"watch app\" */);\r\n}\r\n{code}\r\n\r\nThis needs to be modified to:\r\n{code:javascript}\r\nif (targetInfo.isWatchAppV1Extension || targetInfo.isExtension) {\r\n\taddEmbedBuildPhase.call(this, 'Embed App Extensions', null, 13 /* type \"plugin\" */);\r\n} else if (targetInfo.isWatchAppV2orNewer) {\r\n\taddEmbedBuildPhase.call(this, 'Embed Watch Content', '$(CONTENTS_FOLDER_PATH)/Watch', 16 /* type \"watch app\" */);\r\n}\r\n{code}\r\n\r\nAdding {{|| targetInfo.isExtension}} to the if statement seems to ensure that the .appex files from the extensions are added to the Embedded Binaries of the XCode project.\r\n\r\n[~cbarber] - looking at /iphone/cli/commands/_build.js file in master, it now reads:\r\n{code:javascript}\r\nif (targetInfo.isWatchAppV2orNewer) {\r\n\taddEmbedBuildPhase.call(this, 'Embed Watch Content', '$(CONTENTS_FOLDER_PATH)/Watch', 16 /* type \"watch app\" */);\r\n}\r\n{code}\r\n\r\nI would think this will mean that all non-watch 2 extensions will not work. I think the new code should read:\r\n{code:javascript}\r\nif (targetInfo.isWatchAppV2orNewer) {\r\n\taddEmbedBuildPhase.call(this, 'Embed Watch Content', '$(CONTENTS_FOLDER_PATH)/Watch', 16 /* type \"watch app\" */);\r\n} else {\r\n\taddEmbedBuildPhase.call(this, 'Embed App Extensions', null, 13 /* type \"plugin\" */);\r\n}\r\n{code}\r\n\r\nIs there an example of a Extension that should not appear in the Embedded Binaries section?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2016-03-18T02:09:36.000+0000", "updated": "2016-03-18T09:08:38.000+0000" }, { "id": "380070", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Excellent news [~jeffbonnes]!", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2016-03-18T09:08:56.000+0000", "updated": "2016-03-18T09:08:56.000+0000" }, { "id": "380075", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Great efford [~jeffbonnes]. Can you submit a Pull Request on Github so people can use it from the Core in future versions? Would greatly appreciate that!", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-03-18T10:17:33.000+0000", "updated": "2016-03-18T10:17:33.000+0000" }, { "id": "380763", "author": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "body": "[~jeffbonnes] If I'm understanding you correctly, you're saying we should add {{|| targetInfo.isExtension}}. However adding that is pointless since the code can be simplified to your last snippet: \r\n\r\n{code}\r\nif (targetInfo.isWatchAppV2orNewer) {\r\n\taddEmbedBuildPhase.call(this, 'Embed Watch Content', '$(CONTENTS_FOLDER_PATH)/Watch', 16 /* type \"watch app\" */);\r\n} else {\r\n\taddEmbedBuildPhase.call(this, 'Embed App Extensions', null, 13 /* type \"plugin\" */);\r\n}\r\n{code}\r\n\r\nThat makes sense to me. That if-block won't even get touched if it's not an extension and if it's not a WatchApp v2 or newer, then it's a WatchApp v1 or an extension.\r\n\r\nSo, if I'm following you, then https://github.com/appcelerator/titanium_mobile/pull/7890 should be changed to reflect the suggested lines above and not add {{|| targetInfo.isExtension}}.", "updateAuthor": { "name": "cbarber", "key": "cbarber", "displayName": "Chris Barber", "active": true, "timeZone": "America/Chicago" }, "created": "2016-03-28T03:55:53.000+0000", "updated": "2016-03-28T03:55:53.000+0000" }, { "id": "380777", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "[~cbarber] Makes sense, updated PR.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-03-28T09:03:46.000+0000", "updated": "2016-03-28T09:03:46.000+0000" }, { "id": "380778", "author": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "body": "Agree 100% - thanks guys.", "updateAuthor": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "created": "2016-03-28T09:20:54.000+0000", "updated": "2016-03-28T09:20:54.000+0000" }, { "id": "383994", "author": { "name": "dkcarmo", "key": "dkcarmo", "displayName": "Daniel Kunzler", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I'd love to see this important fix in a release earlier than 5.4.0, if possible.", "updateAuthor": { "name": "dkcarmo", "key": "dkcarmo", "displayName": "Daniel Kunzler", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-04-26T23:14:12.000+0000", "updated": "2016-04-26T23:14:12.000+0000" }, { "id": "384000", "author": { "name": "dirleidionisio", "key": "dirleidionisio", "displayName": "Dirlei Dionísio", "active": true, "timeZone": "America/Sao_Paulo" }, "body": "Me too.", "updateAuthor": { "name": "dirleidionisio", "key": "dirleidionisio", "displayName": "Dirlei Dionísio", "active": true, "timeZone": "America/Sao_Paulo" }, "created": "2016-04-27T00:58:52.000+0000", "updated": "2016-04-27T00:58:52.000+0000" }, { "id": "384002", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~hansknoechel] can you build a back port for 5.3.X for this? Don't merge yet though.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-04-27T01:42:07.000+0000", "updated": "2016-04-27T01:42:07.000+0000" }, { "id": "384041", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR (5_3_X): https://github.com/appcelerator/titanium_mobile/pull/7968", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-04-27T07:34:55.000+0000", "updated": "2016-04-27T07:34:55.000+0000" }, { "id": "384294", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Backport merged. [~hansknoechel] are you able to quickly have the test app for QE with regards to this fix?", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-04-29T02:40:27.000+0000", "updated": "2016-04-29T02:40:27.000+0000" }, { "id": "384519", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "h4. Steps to Test\r\n1. Create a native Titanium App *appc new*\r\n2. Example app name is {{titaniumShare}}, the in tiapp.xml will be something like {{com.appcelerator.sg.titaniumShare}} \r\n3. Open Xcode and create new project {{File->New Project->Other->Empty}}\r\n4. Name it {{titaniumShare}}\r\n4. {{File->New->Target->Application Extension->Share Extension}}\r\n5. Name it {{titaniumShare}} and change Organization Identifier to {{com.appcelerator.sg.titaniumShare}} so that the Bundle Indemnifier is {{com.appcelerator.sg.titaniumShare.titaniumShare}}\r\n6. If you wish, you can activate scheme when prompted, it doesn't matter. \r\n7. Create folder {{extensions}} in Titanium Project folder and copy the Xcode extension project into it.\r\n8. In tiapp.xml, include these properties in section\r\n{code}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n{code}\r\n10. *appc run -p ios*\r\n\r\nh4. Expected Result\r\nOpen Safari in device or simulator. Navigate to any website. Click the share button-> more, you will see titaniumShare. Before this PR, this is not shown.\r\n\r\nTitanium sample app: https://github.com/cheekiatng/titaniumShare\r\n(Although the sample app is written using Titanium CLI, It's recommended to use appc as stated in the reproduction steps)", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-05-03T04:05:27.000+0000", "updated": "2016-05-03T05:44:45.000+0000" }, { "id": "384578", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "This is nice! [~cng] how would a developer be able to hand the file over to the Titanium iOS app? It would be great to build a sample app around that but I need some more context. ", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2016-05-03T13:31:05.000+0000", "updated": "2016-05-03T13:31:05.000+0000" }, { "id": "384619", "author": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Thanks Chee Kiat Ng. \r\n\r\nFokke's question makes lot of sense in this case, as biggest issue from this point is that the share extension has to completely handle by itself the file received and get the user back to the host app from where is sharing the content. This is normally done by creating a native framework shared by the containing app and the extension, so both have the necessary code to handle the file. But I can't see how a share extension could share a framework with a titanium project.\r\n\r\nSo, in my understanding, there are only two options: 1) write native code in the share extension to handle the file received or 2) launch the ti app and let it handle the file.\r\n\r\nThis is a big challenge, as Apple expects that the containing app (the ti app, to be clear) is not opened during the process at all. Precisely, the share extension's design makes unnecessary to open the app and doing so is considered a bad practice, but I can't see how this could be avoided with in titanium projects. The only option would be, as mentioned, implement the logic in the extension, which I guess is a no-go for most ti developers (in our case, it would mean to rewrite most of the app to native). At least in my case, I would accept option 2), at least until something better can be achieved with titanium.\r\n\r\nIn this sense, this link may help on how to send the file to the containing app from the extension:\r\nhttp://stackoverflow.com/questions/32228182/code-to-share-file-path-file-between-a-share-extension-and-ios-app\r\n\r\nAlso I think both apps (the app and the extension) must be part of an App Group, as explained here\r\nhttps://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW19\r\n\r\nI'm trying by myself, but couldn't make it work yet. I'll comment here if get something. \r\n\r\n\r\nHope it helps.", "updateAuthor": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-05-03T17:52:13.000+0000", "updated": "2016-05-03T17:52:13.000+0000" }, { "id": "384630", "author": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "body": "We have a different situation as our Extension is a Document Provider, but we did have to write Native Code in the Extension to do quite a lot. It did duplicate a lot of logic we have in our Ti app.", "updateAuthor": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "created": "2016-05-03T20:27:54.000+0000", "updated": "2016-05-03T20:27:54.000+0000" }, { "id": "384632", "author": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Thanks, Jeff, good to know. I will implement also the Document Provider extension, so any advice is more than welcome.\r\n\r\nIs that any public example we can look at?\r\n\r\n", "updateAuthor": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-05-03T20:50:21.000+0000", "updated": "2016-05-03T20:50:21.000+0000" }, { "id": "384677", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~jaraen] Maybe we can wrap [this solution via nsuserdefaults|http://stackoverflow.com/a/33795269/4626813] in a Swift/Obj-C lib and Ti API to pass data to the Titanium iOS app for processing, which would then notify the extension with the result so it can update the extension UI (with the error or saying it has been done)?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2016-05-04T08:00:03.000+0000", "updated": "2016-05-04T08:00:03.000+0000" }, { "id": "384679", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Yes I think this is pretty exciting as well. I hope the above merged PR , as well as the related today extension helps to open more possibilities of the usage of extensions with titanium SDK. \r\n\r\nThanks everyone for your input. Will appreciate very much if we don't clutter in this ticket, and create new specific tickets instead of improvements or new features with regards to ios extensions. And of course, PRs are very welcomed :)", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-05-04T08:10:18.000+0000", "updated": "2016-05-04T08:10:18.000+0000" }, { "id": "384687", "author": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "That's the plan, Fokke. I should be able to spend some time on it this week, I'll let you know. ", "updateAuthor": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-05-04T08:51:30.000+0000", "updated": "2016-05-04T08:51:30.000+0000" }, { "id": "385409", "author": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "updateAuthor": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-05-11T16:10:41.000+0000", "updated": "2016-05-11T16:11:26.000+0000" }, { "id": "385480", "author": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "body": "@jaraen - are your extensions also setup to access the application groups? A copy of my Entitlements.plist that works in my Titanium project is below:\r\n\r\n\r\n\r\n\tcom.apple.security.application-groups\r\n\t\r\n\t\tgroup.com.geeksinc.documentexample\r\n\t\r\n\r\n\r\n\r\nAnd in my extensions (in XCode) for each Target:\r\n!https://dl.dropboxusercontent.com/u/843217/AppGroupInXCode.png!\r\n\r\nAnd it needs to be in the Entitlements.plist for each extension - I missed this the first time.\r\n\r\nAlso, the App Group needs to be setup in the Apple Developer Portal and your Provisioning Profile for your Titanium app must have been generated after the App Group was added to the App Services of the App Id. XCode may do this for you, but better to do it yourself to make sure.", "updateAuthor": { "name": "jeffbonnes", "key": "jeffbonnes", "displayName": "Jeff Bonnes", "active": true, "timeZone": "Australia/Sydney" }, "created": "2016-05-12T00:12:50.000+0000", "updated": "2016-05-12T00:14:03.000+0000" }, { "id": "385524", "author": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "body": "thanks, @jeffbonnes\r\n\r\nsure, I did that and reviewed several times. There's no error or pending fixes in the extension project. However, if I open in xCode the project generated by titanium, the group appears in red. There are no errors, the group name is red. Pretty weird... Worths saying that I've tried with two different projects and had same result. \r\n\r\nA couple of questions: are you able to run the extension on simulator? Should it work without setting any profile in the extension tag? If so, are you launching the project specifying any provisioning profile? Or do you trust in default xcode generated profiles?\r\n\r\nThanks!", "updateAuthor": { "name": "jaraen", "key": "jaraen", "displayName": "Javier Rayon", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-05-12T11:15:28.000+0000", "updated": "2016-05-12T11:15:28.000+0000" }, { "id": "385823", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-05-16T20:11:49.000+0000", "updated": "2016-05-16T20:11:49.000+0000" }, { "id": "386070", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-05-18T17:17:46.000+0000", "updated": "2016-05-18T17:53:45.000+0000" }, { "id": "386534", "author": { "name": "emerriman", "key": "emerriman", "displayName": "Eric Merriman ", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Closing as implemented. ", "updateAuthor": { "name": "emerriman", "key": "emerriman", "displayName": "Eric Merriman ", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-05-23T21:47:22.000+0000", "updated": "2016-05-23T21:47:22.000+0000" } ], "maxResults": 55, "total": 55, "startAt": 0 } } }