{ "id": "175429", "key": "TIMOB-28077", "fields": { "issuetype": { "id": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "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": "21051", "description": "", "name": "Release 9.2.0", "archived": false, "released": true, "releaseDate": "2020-09-23" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2020-09-11T18:31:13.000+0000", "created": "2020-08-11T19:39:28.000+0000", "epic": { "id": 175154, "key": "TIMOB-27964", "name": "Support iOS 14", "summary": "iOS: Support iOS 14 and Xcode 12", "color": { "key": "color_1" }, "done": false }, "priority": { "name": "High", "id": "2" }, "labels": [ "bonjour", "iOS" ], "versions": [], "issuelinks": [ { "id": "58625", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "175430", "key": "TIMOB-28078", "fields": { "summary": "iOS14: Expose new APIs Titanium.Network.HTTPClient which will require while accessing local http server", "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 } } } } ], "assignee": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2020-09-11T18:31:13.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": "In iOS 14, Apple has put restriction on accessing local network. It requires user permission. \r\nTo show the prompt developer need to add key [NSLocalNetworkUsageDescription|https://developer.apple.com/documentation/bundleresources/information_property_list/nslocalnetworkusagedescription?language=objc] in tiapp.xml and if using Bonjure Service, that need to be added in info.plist using key [NSBonjourServices |https://developer.apple.com/documentation/bundleresources/information_property_list/nsbonjourservices] . More detail can be found in WWDC video https://developer.apple.com/videos/play/wwdc2020/10110/.\r\nIn iOS 14, new error [constant|https://developer.apple.com/documentation/foundation/nsnetserviceserror/nsnetservicesmissingrequiredconfigurationerror?language=objc] is given. In titanium, it need to added in Ti.Network.BonjureService and expose as error string. ", "attachment": [], "flagged": false, "summary": "iOS14: Expose new error type in Bonjure Service and update doc to align with Local n/w privacy restrictions ", "creator": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "closedSprints": [ { "id": 1204, "state": "closed", "name": "2020 Sprint 17", "startDate": "2020-08-17T15:48:00.000Z", "endDate": "2020-08-28T15:48:00.000Z", "completeDate": "2020-08-31T15:36:28.040Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "456426", "author": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Test Case -\r\n\r\n{code:java}\r\nvar win = Ti.UI.createWindow({\r\n\tbackgroundColor: 'white'\r\n});\r\n\r\nvar label = Ti.UI.createLabel({\r\n\ttop: 150,\r\n\ttext: 'Publish Service'\r\n});\r\n\r\nlabel.addEventListener('click', function(e) {\r\n\t// Create the Bonjour Service\r\n\tvar localService = Ti.Network.createBonjourService({\r\n\t name: 'example',\r\n\t type: '_test._tcp',\r\n\t domain: 'local.'\r\n\t});\r\n\r\n\t// Create the socket we'll tie to the service\r\n\tvar hostname = Ti.Platform.address;\r\n\tvar bonjourSocket = Ti.Network.Socket.createTCP({\r\n\t host: hostname,\r\n\t port: 40404,\r\n\t accepted: function (e) {\r\n\t \talert(\"Listening socket <\" + e.socket + \"> accepted incoming connection <\" + e.inbound + \">\");\r\n\t Ti.API.info(\"Listening socket <\" + e.socket + \"> accepted incoming connection <\" + e.inbound + \">\");\r\n\t e.inbound.write(Ti.createBuffer({\r\n\t value: 'You have been connected to a listening socket.\\r\\n'\r\n\t }));\r\n\t e.inbound.close();\r\n\t },\r\n\t error: function (e) {\r\n\t \talert(\"Socket <\" + e.socket + \"> encountered error when listening\");\r\n\t Ti.API.error(\"Socket <\" + e.socket + \"> encountered error when listening\");\r\n\t Ti.API.error(\" error code <\" + e.errorCode + \">\");\r\n\t Ti.API.error(\" error description <\" + e.error + \">\");\r\n\t }\r\n\t});\r\n\r\n\tbonjourSocket.listen();\r\n\r\n\tbonjourSocket.accept({ timeout: 10000 });\r\n\r\n\tlocalService.publish(bonjourSocket, function (err, success) {\r\n\t\tif (!success) {\r\n\t\t\talert('Service publish failed:' +err.message);\r\n\t\t} else {\r\n\t\t\talert('Service published successfully');\r\n\t\t}\r\n\t});\t\r\n});\r\n\r\nwin.add(label);\r\n\r\nvar searchLabel = Ti.UI.createLabel({\r\n\ttop: 300,\r\n\ttext: 'Start Searching'\r\n});\r\n \r\nsearchLabel.addEventListener('click', function(e) {\r\n \r\n\tvar httpBonjourBrowser = Ti.Network.createBonjourBrowser({\r\n\t serviceType: '_test._tcp',\r\n\t domain: 'local.'\r\n\t});\r\n \r\n\thttpBonjourBrowser.addEventListener('updatedservices', function (e) {\r\n\t for (var service of e.services) {\r\n\t service.resolve(120, (err, success) => {\r\n\t console.log(service.socket);\r\n\t console.log(service.socket.port);\r\n\t console.log(service.socket.host);\r\n\t });\r\n\t }\r\n\r\n\t alert('success')\r\n\t});\r\n \r\n\t// Start searching\r\n\thttpBonjourBrowser.search();\r\n});\r\n\r\nwin.add(searchLabel);\r\nwin.open();\r\n{code}\r\n\r\nHow to Test - \r\n1. Create an app using and add mentioned test case. \r\n2. Run it on device with iOS 14.\r\n3. Click on 'Publish Service'. It should show error in alert.\r\n4. Add key 'NSLocalNetworkUsageDescription' and key 'NSBonjourServices' in tiapp.xml (see the doc). Run again.\r\n5. Click on 'Publish Service'. It should show prompt to ask user permission. On click of 'Ok', it should show success alert.\r\n6. Click on 'Start Searching', it should show success alert.\r\n7. Delete the app from mobile. Remove the added keys from tiapp.xml.\r\n8. Run again. \r\n9. Click on 'Start Searching'. It should throw exception.\r\n10. Add keys again as mentioned in step 4.\r\n11. Run again. It should show prompt to ask user permission. Click 'Ok'. It should not throw exception.\r\n", "updateAuthor": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-08-11T23:29:10.000+0000", "updated": "2020-08-12T18:22:31.000+0000" }, { "id": "456442", "author": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR - https://github.com/appcelerator/titanium_mobile/pull/11896", "updateAuthor": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-08-12T17:47:28.000+0000", "updated": "2020-08-12T17:47:28.000+0000" }, { "id": "456642", "author": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "body": "FR Passed.\r\nWaiting for Jenkins build", "updateAuthor": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-08-28T16:23:27.000+0000", "updated": "2020-08-28T16:23:27.000+0000" }, { "id": "456851", "author": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified on:\r\nMac OS: 10.15.4\r\nSDK: 9.2.0.v20200911073932, 9.3.0.v20200911052140\r\nAppc CLI: 8.1.0\r\nJDK: 11.0.4\r\nNode: 10.17.0\r\nStudio: 6.0.0.202005141803\r\nXcode: 12.0 Beta6\r\niPhone 7Plus(v14.0 Beta6)", "updateAuthor": { "name": "ssekhri", "key": "ssekhri", "displayName": "Satyam Sekhri", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2020-09-11T18:31:13.000+0000", "updated": "2020-09-11T18:31:13.000+0000" } ], "maxResults": 5, "total": 5, "startAt": 0 } } }