{ "id": "151381", "key": "TIMOB-19567", "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": "16997", "name": "Release 5.2.0", "archived": false, "released": true, "releaseDate": "2016-02-23" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2015-10-29T20:38:40.000+0000", "created": "2015-09-22T14:22:37.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "handoff" ], "versions": [ { "id": "16925", "description": "WatchKit Support--all going into 5.0 now", "name": "Release 5.0.0", "archived": true, "released": true, "releaseDate": "2015-09-16" } ], "issuelinks": [ { "id": "49531", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "152467", "key": "TIMOB-19824", "fields": { "summary": "Automatically call needsSave when user activity is updated", "status": { "description": "The issue is open and ready for the assignee to start work on it.", "name": "Open", "id": "1", "statusCategory": { "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "priority": { "name": "None", "id": "6" }, "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false } } } } ], "assignee": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "updated": "2016-02-23T10:47:24.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": "While I was working on https://github.com/appcelerator-developer-relations/appc-sample-handoff when our SDK and Apple's were still not GA and since they became GA it seems like the behaviour around {{useractivitywillsave}} has changed:\r\n\r\n* Before it fired directly after setting {{needsSave:true}} but now it only does before the activity is handed off. This is expected behaviour, so I guess OK.\r\n* Before I any change I did to the activity's {{userInfo}} in the event listener for {{useractivitywillsave}} would be received by the {{continueactivity}} event on the other device. But now it is no longer. This is not expected behaviour, so definitely a bug!\r\n\r\nTo reproduce:\r\n\r\n1. Build https://github.com/appcelerator-developer-relations/appc-sample-handoff to 2 devices\r\n2. Make a change to the {{needsSave}} tab's title/message and continue on the other device\r\n3. Check the logs on both and see that while the {{userInfo}} was updated in the {{useractivitywillsave}} on the first, it is not received in {{continueactivity}} on the other.\r\n\r\nThis seems like a serious bug because this makes handoff not usable for dynamic content.", "attachment": [], "flagged": false, "summary": "Last change made after useractivitywillsave does not make it to other device", "creator": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "subtasks": [], "reporter": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "environment": "SDK 5.0.0.GA\r\niOS 9.0 GA", "closedSprints": [ { "id": 517, "state": "closed", "name": "2015 Sprint 22 SDK", "startDate": "2015-10-24T00:30:42.059Z", "endDate": "2015-11-07T01:30:00.000Z", "completeDate": "2015-11-09T02:37:29.441Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "365208", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~fokkezb], try out my classic app.js sample code\r\n{code}\r\nvar win = Ti.UI.createWindow({\r\n\ttitle: 'testActibity',\r\n\tbackgroundColor: 'white'\r\n});\r\n\r\nvar btn = Ti.UI.createButton({\r\n\ttop: 40,\r\n\ttitle: 'make activity current'\r\n});\r\n\r\nbtn.addEventListener('click',function(e){\r\n\tif (activity.supported) {\r\n\t activity.becomeCurrent();\r\n\t}\r\n});\r\n\r\nvar btn2 = Ti.UI.createButton({\r\n\ttop: 80,\r\n\ttitle: 'needs save'\r\n});\r\n\r\nbtn2.addEventListener('click',function(e){\r\n\tactivity.needsSave = true;\r\n});\r\n\r\nwin.add(btn);\r\nwin.add(btn2);\r\nwin.open();\r\n\r\nvar activity = Ti.App.iOS.createUserActivity({\r\n activityType: 'com.appcelerator.sg.SGTestHandoff2.needssave',\r\n title: 'first activity',\r\n userInfo: {\r\n body: 'first activity'\r\n }\r\n});\r\nactivity.addEventListener('useractivitywillsave', onUseractivitywillsave);\r\nactivity.addEventListener('useractivitywascontinued', onUseractivitywascontinued);\r\n\r\nTi.App.iOS.addEventListener('continueactivity', onContinueactivity);\r\n\r\n\r\n\r\n/**\r\n * Called when our activity was continued on another device.\r\n */\r\nfunction onContinueactivity(e) {\r\n\r\n\t// We only respond to the writing activity\r\n\tif (e.activityType !== 'com.appcelerator.sg.SGTestHandoff2.needssave') {\r\n\t\treturn;\r\n\t}\r\n\r\n\talert('Ti.App.iOS:continueactivity: ' + JSON.stringify(e));\r\n\r\n\t// Update our content with activity handed off to us\r\n\r\n}\r\n\r\n/**\r\n * Called before our activity is continued on another device so we can update its state.\r\n */\r\nfunction onUseractivitywillsave(e) {\r\n\talert('Ti.App.iOS.UserActivity:useractivitywillsave ' + JSON.stringify(e));\r\n\r\n\tactivity.title = 'before you go';\r\n\r\n\tactivity.userInfo = {\r\n\t\tbody: 'i changed my body text'\r\n\t};\r\n\r\n\tTi.API.info('Updated activity: '+ activity.title +', ' + activity.userInfo.body);\r\n}\r\n\r\n/**\r\n * Called when our activity was continued on another device.\r\n */\r\nfunction onUseractivitywascontinued(e) {\r\n\talert('Ti.App.iOS.UserActivity:useractivitywascontinued ' + JSON.stringify(e));\r\n}\r\n{code}\r\nand include in tiapp.xml\r\n{code}\r\n NSUserActivityTypes\r\n\t\t \r\n\t\t com.appcelerator.sg.SGTestHandoff2.needssave\r\n\t\t \r\n{code}\r\nIt seems to be behaving correctly. \r\n\r\nh4. Steps to verify\r\n1. install app on 2 devices\r\n2. on device A, open the app, and press \"make activity current\"\r\n3. An alert will pop up, indicating will save event with the current activity info\r\n4. on device B, continue the activity via the lock screen\r\n5. alert will pop up in device A, indicating will save event with the new activity info\r\n6. close the alert\r\n7. alert will pop up in device A, indicating new activity is continued on another device\r\n8. alert will pop up in device B, indicating new activity is continuing, with NEW activity info", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-09-29T06:07:28.000+0000", "updated": "2015-09-29T06:07:28.000+0000" }, { "id": "365209", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Though i noticed, i completely did not use 'needSave' property. i'm assuming that's true by default.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-09-29T06:08:04.000+0000", "updated": "2015-09-29T06:08:04.000+0000" }, { "id": "365222", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~cng] {{useractivitywillsave}} will always fire right after {{becomeCurrent()}} regardless of {{needsSave}}, but indeed I see that in your sample it is also fires when you handover without first setting {{needsSave}}, while I've also seen it not do that. It seems to be very unpredictable.\r\n\r\nI've modified your sample to better demonstrates what I can still demonstrate going wrong:\r\n\r\n{code}\r\nvar win = Ti.UI.createWindow({\r\n\ttitle: 'testActibity',\r\n\tbackgroundColor: 'white'\r\n});\r\n \r\nvar btn = Ti.UI.createButton({\r\n\ttop: 40,\r\n\ttitle: 'make activity current'\r\n});\r\n \r\nbtn.addEventListener('click',function(e){\r\n\tif (activity.supported) {\r\n\t activity.becomeCurrent();\r\n\t}\r\n});\r\n \r\nvar btn2 = Ti.UI.createButton({\r\n\ttop: 80,\r\n\ttitle: 'needs save'\r\n});\r\n \r\nbtn2.addEventListener('click',function(e){\r\n\tactivity.needsSave = true;\r\n\r\n\tlog.value = log.value + 'Set activity.needsSave=true\\n\\n';\r\n});\r\n \r\nvar btn3 = Ti.UI.createButton({\r\n\ttop: 120,\r\n\ttitle: 'clear log'\r\n});\r\n \r\nbtn3.addEventListener('click',function(e){\r\n\tlog.value = '';\r\n});\r\n\r\nvar log = Ti.UI.createTextArea({\r\n\ttop: 160,\r\n\tright: 0,\r\n\tbottom: 0,\r\n\tleft: 0,\r\n\tfont: {\r\n\t\tfontFamily: 'Courier'\r\n\t},\r\n\teditable: false\r\n});\r\n \r\nwin.add(btn);\r\nwin.add(btn2);\r\nwin.add(btn3);\r\nwin.add(log);\r\nwin.open();\r\n \r\nvar activity = Ti.App.iOS.createUserActivity({\r\n activityType: 'com.appcelerator.sg.SGTestHandoff2.needssave',\r\n title: 'Initial title',\r\n userInfo: {\r\n body: 'Initial body'\r\n }\r\n});\r\nactivity.addEventListener('useractivitywillsave', onUseractivitywillsave);\r\n \r\nTi.App.iOS.addEventListener('continueactivity', onContinueactivity);\r\n \r\n/**\r\n * Called when our activity was continued on another device.\r\n */\r\nfunction onContinueactivity(e) {\r\n \r\n\t// We only respond to the writing activity\r\n\tif (e.activityType !== 'com.appcelerator.sg.SGTestHandoff2.needssave') {\r\n\t\treturn;\r\n\t}\r\n\r\n\tlog.value = log.value + 'continueactivity: ' + JSON.stringify(e) + '\\n\\n';\r\n}\r\n \r\n/**\r\n * Called before our activity is continued on another device so we can update its state.\r\n */\r\nfunction onUseractivitywillsave(e) {\r\n\tlog.value = log.value + 'useractivitywillsave: ' + JSON.stringify(e) + '\\n\\n';\r\n\r\n\tvar time = 'Time: ' + Date.now().toString();\r\n \r\n\tactivity.title = time;\r\n\tactivity.userInfo = {\r\n\t\tbody: time\r\n\t};\r\n\r\n\tlog.value = log.value + 'Updated activity with \"' + time + '\": ' + JSON.stringify({\r\n\t\ttitle: activity.title,\r\n\t\tuserinfo: activity.userInfo\r\n\t}) + '\\n\\n';\r\n}\r\n{code}\r\n\r\n*Steps*\r\n\r\n1. Make current on first device\r\n2. Handoff on other device\r\n3. See that the activity the other device received does not have the timestamp set by the first in {{useractivitywillsave}}\r\n\r\n*Logs Device 1*\r\n\r\n{code}\r\nuseractivitywillsave: {\"title\":\"Initial title\",\"activityType\":\"com.appcelerator.sg.SGTestHandoff2.needssave\",\"userInfo\":{\"body\":\"Initial body\"},\"bubbles\":true,\"type\":\"useractivitywillsave\",\"source\":{},\"cancelBubble\":false}\r\n\r\nUpdated activity with \"Time: 1443512899529\": {\"title\":\"Initial title\",\"userinfo\":{\"body\":\"Initial body\"}}\r\n\r\nuseractivitywillsave: {\"title\":\"Time: 1443512899529\",\"activityType\":\"com.appcelerator.sg.SGTestHandoff2.needssave\",\"userInfo\":{\"body\":\"Time: 1443512899529\"},\"bubbles\":true,\"type\":\"useractivitywillsave\",\"source\":{},\"cancelBubble\":false}\r\n\r\nUpdated activity with \"Time: 1443512907367\": {\"title\":\"Time: 1443512907367\",\"userinfo\":{\"body\":\"Time: 1443512907367\"}}\r\n{code}\r\n\r\n*Log Device 2*\r\n\r\n{code}\r\ncontinueactivity: {\"title\":\"Time: 1443512899529\",\"activityType\":\"com.appcelerator.sg.SGTestHandoff2.needssave\",\"userInfo\":{\"body\":\"Time: 1443512899529\"},\"bubbles\":true,\"type\":\"continueactivity\",\"source\":{},\"cancelBubble\":false}\r\n{code}\r\n\r\nAs you can see when I update the activity on device 1 even on that device after setting {{activity.title}} a get on that same variable returns the old value. So there seems to be something wrong there. Sometimes the get does give the right value, sometimes only for the title, other times only the body. Very odd!", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-09-29T07:58:53.000+0000", "updated": "2015-09-29T07:58:53.000+0000" }, { "id": "365536", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Hm. Looking at the code, i think the reason is because of this line:\r\nhttps://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiAppiOSUserActivityProxy.m#L189\r\nsee it fires the event to JS, after which it continues to do what it is supposed to do, to continue activity on another device. So it looks like it won't wait for you to make changes to the activity. that's why you see the race condition. Some thoughts have to be put in on this, this may be a little tricky.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-10-01T09:42:26.000+0000", "updated": "2015-10-01T09:42:26.000+0000" }, { "id": "365572", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "The workaround is to update the activity when you set {{needsSave:true}}, but that's.. well, ugly.\r\n\r\nCould we do a callback or something?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-01T19:25:19.000+0000", "updated": "2015-10-01T19:25:19.000+0000" }, { "id": "365628", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "We could somehow hack it such that the main thread waits for the JS to complete a callback or something, but \r\n1. That sounds like a bad idea\r\n2. i don't think we have ever done something like that in the sdk\r\n\r\nWe might have to consider deprecating and removing this event altogether. users could stick to \"useractivitywascontinued\", used for remembering the state the app was in before continued on to another device. Because i relate a user activity to a app state, and can only imagine a small use case whereby you want to change the activity content on the last minute before it's handed off.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-10-02T07:26:41.000+0000", "updated": "2015-10-02T07:26:41.000+0000" }, { "id": "365632", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Well if we remove it we break parity with the native API. *The* example for handoff is starting an email on your iPhone and continue it on your iPad or Mac. For this typical use case it *is* very important that you can update the activity before it is continued on the other device. I really need we do need to fix this. And until we do we should inform people about the workaround, which is to update the activity when they set {{needsSave:true}}. I will update the blog post that will go out today with that and link to this issue.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-02T08:35:01.000+0000", "updated": "2015-10-02T08:35:01.000+0000" }, { "id": "365717", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~ben.bahrenburg@gmail.com] since you implemented this (right?) any ideas on this issue?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-03T07:54:06.000+0000", "updated": "2015-10-03T07:54:06.000+0000" }, { "id": "365721", "author": { "name": "ben.bahrenburg@gmail.com", "key": "ben.bahrenburg@gmail.com", "displayName": "Ben Bahrenburg", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~fokkezb] what you have as the workaround is the actual behavior. Please reference http://stackoverflow.com/questions/26715531/nsuseractivity-handoff-not-working-for-custom-data\r\n\r\nIf you made any chances you need to update the needsSave property. Sounds like this is just a documentation update. Alternatively we could break with the native API and set the property for the developer. Would suggest the first strategy.", "updateAuthor": { "name": "ben.bahrenburg@gmail.com", "key": "ben.bahrenburg@gmail.com", "displayName": "Ben Bahrenburg", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-10-03T16:29:58.000+0000", "updated": "2015-10-03T16:29:58.000+0000" }, { "id": "365722", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~ben.bahrenburg@gmail.com] I know you need to set {{needsSave:true}} when you have changes that need to be saved before another device continues the activity. That's not the point.\r\n\r\nThe point is that Apple is (somewhat) [clear|https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/Handoff/AdoptingHandoff/AdoptingHandoff.html#//apple_ref/doc/uid/TP40014338-CH2-SW14] that you shouldn't actually update the activity until the {{useractivitywillsave}} event.\r\n\r\n{quote}To update the activity object’s userInfo dictionary efficiently, configure its delegate and set its needsSave property to YES whenever the userInfo needs updating. At appropriate times, Handoff invokes the delegate’s userActivityWillSave: callback, and the delegate can update the activity state.{quote}\r\n\r\nAnd *that* is not (always) working in our Titanium implementation because the Obj-C thread doesn't wait for the JS event to be finished before allowing the other device to continue. Which causes the other device to not always get the updated information but rather the previous state.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-03T17:23:04.000+0000", "updated": "2015-10-03T17:24:25.000+0000" }, { "id": "365723", "author": { "name": "ben.bahrenburg@gmail.com", "key": "ben.bahrenburg@gmail.com", "displayName": "Ben Bahrenburg", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~fokkezb] you are not going to be able to have the Obj-C wait for the JS event to finish. This is just a delegate event that is fired in native, that then raises the event in JS.\r\n\r\nTruthfully you should be re-building your activity on the other side of your application if there is concern over latency.", "updateAuthor": { "name": "ben.bahrenburg@gmail.com", "key": "ben.bahrenburg@gmail.com", "displayName": "Ben Bahrenburg", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-10-03T17:33:36.000+0000", "updated": "2015-10-03T17:33:36.000+0000" }, { "id": "365769", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "I don't get what you mean with re-building. Surely we need to be able to get this working as Apple has documented it should work?", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-05T08:05:41.000+0000", "updated": "2015-10-05T08:05:41.000+0000" }, { "id": "365779", "author": { "name": "ben.bahrenburg@gmail.com", "key": "ben.bahrenburg@gmail.com", "displayName": "Ben Bahrenburg", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~fokkezb] see [~cng] comment he sums up your options well. Even read your second to last statement with some thought, i.e. you want ObjC to wait for JS in a delegate call.... think about what you just said. I think the key is how do you work around this in your example. Personally when I coded the hand-off part of my application, using this code, I never had to use this event.", "updateAuthor": { "name": "ben.bahrenburg@gmail.com", "key": "ben.bahrenburg@gmail.com", "displayName": "Ben Bahrenburg", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-10-05T13:21:14.000+0000", "updated": "2015-10-05T13:24:52.000+0000" }, { "id": "365879", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "I know it works fine if you update the activity before/when you set {{needsSave:true}} it would just be better if we can make our implementation follow Apple's best practices.\r\n\r\nIf that is technically impossible then we should indeed remove the {{useractivitywillsave}} event and tell people that in contrast to what Apple says they need to update the activity where they set {{needsSave:true}}.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-06T09:51:34.000+0000", "updated": "2015-10-06T09:51:34.000+0000" }, { "id": "368094", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "PR here: https://github.com/appcelerator/titanium_mobile/pull/7357\r\nto deprecate useractivitywillsave to avoid confusion.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-10-28T07:57:40.000+0000", "updated": "2015-10-28T07:57:40.000+0000" }, { "id": "368109", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~cng] Added a few comments to the PR.\r\n\r\nIf we don't expect to ever be able to restore {{useractivitywillsave}} it would be good to look into if it wouldn't be better if we call needsSave automatically whenever the user makes a change to the user activity.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-28T10:39:53.000+0000", "updated": "2015-10-28T10:39:53.000+0000" }, { "id": "368205", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~fokkezb] it sure sounds reasonable. maybe new a ticket for that?", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-10-28T23:50:02.000+0000", "updated": "2015-10-28T23:50:02.000+0000" }, { "id": "368280", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "Done: TIMOB-19567", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2015-10-29T10:54:27.000+0000", "updated": "2015-10-29T10:54:27.000+0000" }, { "id": "368340", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR approved!", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2015-10-29T20:39:01.000+0000", "updated": "2015-10-29T20:39:01.000+0000" }, { "id": "377565", "author": { "name": "htbryant", "key": "htbryant", "displayName": "Harry Bryant", "active": true, "timeZone": "Europe/London" }, "body": "Verified as fixed, This was tested using two iOS9 devices, and an iOS9 to iOS8 device. info made by {{useractivitywillsave}} returns correct values on multiple tries, and the information received by Device B is reflected correctly.\r\n\r\nTested on:\r\n\r\niPhone 6Plus device (9.0.2) , iPhone 6S Plus (9.2.1) & iOS8.4 Device\r\nMac OSX El Capitan 10.11.3 (15D21)\r\nTi SDK: 5.2.0.v20160220080449\r\nAppc Studio: 4.5.0.201602170821\r\nAppc NPM: 4.2.3-2\r\nApp CLI: 5.2.0-269\r\nXcode 7.2\r\nNode v4.2.6\r\nproduction\r\n\r\n*Closing ticket.*", "updateAuthor": { "name": "htbryant", "key": "htbryant", "displayName": "Harry Bryant", "active": true, "timeZone": "Europe/London" }, "created": "2016-02-22T22:49:04.000+0000", "updated": "2016-02-22T22:49:04.000+0000" }, { "id": "377635", "author": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "body": "[~htbryant] not sure I get your test report. The event should give a deprecation message now because it does _not_ (always) work as expected.", "updateAuthor": { "name": "fokkezb", "key": "fokke", "displayName": "Fokke Zandbergen", "active": true, "timeZone": "Europe/Amsterdam" }, "created": "2016-02-23T10:47:24.000+0000", "updated": "2016-02-23T10:47:24.000+0000" } ], "maxResults": 21, "total": 21, "startAt": 0 } } }