{ "id": "162772", "key": "TIMOB-23812", "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": "18253", "name": "Release 5.5.0", "archived": false, "released": true, "releaseDate": "2016-09-13" }, { "id": "18264", "name": "hyperloop 1.2.7", "archived": false, "released": true, "releaseDate": "2017-02-06" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2016-09-09T13:59:17.000+0000", "created": "2016-08-23T23:35:05.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "qe-5.5.0" ], "versions": [ { "id": "18253", "name": "Release 5.5.0", "archived": false, "released": true, "releaseDate": "2016-09-13" } ], "issuelinks": [ { "id": "52572", "type": { "id": "10020", "name": "Depends", "inward": "is dependent of", "outward": "depends on" }, "inwardIssue": { "id": "162768", "key": "TIMOB-23808", "fields": { "summary": "Hyperloop: iOS - Example application not building with Xcode 8 because of Swift-Error", "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": "52728", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "163234", "key": "TIMOB-23911", "fields": { "summary": "Hyperloop: iOS: Improve the way properties are generated", "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": "4", "description": "An improvement or enhancement to an existing feature or task.", "name": "Improvement", "subtask": false } } } } ], "assignee": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "updated": "2016-09-15T18:20:22.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "13715", "name": "Hyperloop", "description": "Hyperloop project" }, { "id": "10206", "name": "iOS", "description": "iOS Platform" }, { "id": "10207", "name": "Tooling" } ], "description": "In Xcode 8 beta 6 on the build of the application the instance of {{redColor}} is generated but not the class.\r\n\r\nh4. Steps to reproduce:\r\n# Download the Xcode beta \r\n# Select to use the beta version of Xcode {{xcode-select -s }}\r\n# Create a new application with hyperloop \r\n# Use the app.js below in the application\r\n# {{appc run -p ios}}\r\n# Select to use the GA version of Xcode {{xcode-select -s }}\r\n# {{appc run -p ios}}\r\n\r\nh4. App.js\r\n\r\n{noformat}\r\nvar UIView = require('UIKit/UIView'),\r\n\tUIColor = require('UIKit/UIColor'),\r\n\tUIImage = require('UIKit/UIImage'),\r\n\tCGRectMake = require('CoreGraphics').CGRectMake;\r\n\r\nvar win = Ti.UI.createWindow({\r\n\tbackgroundColor: 'white',\r\n\tlayout: 'vertical'\r\n});\r\nvar view = UIView.alloc().initWithFrame(CGRectMake(10, 10, 50, 50));\r\nview.backgroundColor = UIColor.redColor();\r\nwin.add(view);\r\nwin.open();\r\n{noformat}\r\n\r\n\r\n\r\nh4. Actual when using Xcode 8 beta 6\r\n{noformat}\r\n[ERROR] Script Error {\r\n[ERROR] column = 40;\r\n[ERROR] line = 11;\r\n[ERROR] message = \"UIColor.redColor is not a function. (In 'UIColor.redColor()', 'UIColor.redColor' is undefined)\";\r\n[ERROR] sourceURL = \"file:///Users/Josh/Library/Developer/CoreSimulator/Devices/D5EEC5AB-078C-46AA-AC55-05BBBD410CB7/data/Containers/Bundle/Application/6680ADD3-DB71-4F72-8610-D837D5476666/Hyperloop%20forward%20testing.app/app.js\";\r\n[ERROR] } \r\n{noformat}\r\n\r\n\r\nh4. Expected\r\nThe application runs as it does in Xcode 7.3.1\r\n", "attachment": [], "flagged": false, "summary": "Hyperloop: UIColor type properties is not working with Xcode 8 beta ", "creator": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "subtasks": [], "reporter": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "environment": "Mac OSX El Capitan 10.11.6\r\n
Appc NPM: 4.2.7\r\nAppc CLI: 5.5.0-5\r\n
Ti SDK: 5.5.0.v20160822000355\r\nHyperloop: 1.2.6\r\nCocoapods: 1.0.1\r\nXcode 8 beta 6 / 7.3.1\r\nNode: v4.4.4", "closedSprints": [ { "id": 705, "state": "closed", "name": "2016 Sprint 18 Tooling", "startDate": "2016-08-27T00:16:26.485Z", "endDate": "2016-09-10T00:16:00.000Z", "completeDate": "2016-09-13T20:21:37.063Z", "originBoardId": 199 } ], "comment": { "comments": [ { "id": "394008", "author": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "body": "I will investigate this issue to see if anything else have been affected in the Xcode beta. ", "updateAuthor": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "created": "2016-08-23T23:35:56.000+0000", "updated": "2016-08-23T23:35:56.000+0000" }, { "id": "394011", "author": { "name": "jhaynie", "key": "jhaynie", "displayName": "Jeff Haynie", "active": false, "timeZone": "America/Los_Angeles" }, "body": "I helped Josh trouble shoot. \r\n\r\nIt looks like based on the HL code gen output that in the newer SDK UIColor redColor is now both +[UIColor redColor] and -[UIColor redColor] and the generation (JS) only generates the instance and not both the instance and the class methods.\r\n", "updateAuthor": { "name": "jhaynie", "key": "jhaynie", "displayName": "Jeff Haynie", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-08-23T23:55:55.000+0000", "updated": "2016-08-23T23:55:55.000+0000" }, { "id": "394088", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Yep, Xcode 8 introduced the color-properties to (probably) ease the syntax on the Obj-C side - which also generates the property getter / class method.\r\n{code:objc}\r\n@property(class, nonatomic, readonly) UIColor *redColor; \r\n{code}\r\nThey seem to use the also in Xcode 8 introduced {{UIKIT_DEFINE_AS_PROPERTIES}} statement to switch between the (class)-property and class-method usage. So in this case, the above statement seems to be true and so the usual class-methods as we know them are not even compiled by iOS. \r\n\r\nBonus: The statement is defined as the following:\r\n{code:objc}\r\n#define UIKIT_DEFINE_AS_PROPERTIES (!defined(SWIFT_CLASS_EXTRA) || (defined(SWIFT_SDK_OVERLAY_UIKIT_EPOCH) && SWIFT_SDK_OVERLAY_UIKIT_EPOCH >= 1))\r\n{code}\r\n\r\nSo we may need to investigate if it makes sense to make it *a)* detect the define and property automcatically or *b)* stick to the \"old\" behavior for now.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-08-24T12:31:01.000+0000", "updated": "2016-08-25T11:03:43.000+0000" }, { "id": "394779", "author": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "body": "So the main problem here is that Hyperloop does not differentiate between instance and class properties. As Jeff already pointed out, it recognizes the property but treats it as an instance property, thus resulting in wrong code generated in the JS files. I'll update the metabase generator and the templates to also support the new class level properties.", "updateAuthor": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-08-30T13:54:58.000+0000", "updated": "2016-08-30T13:54:58.000+0000" }, { "id": "394958", "author": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "body": "WIP PR: https://github.com/appcelerator/hyperloop.next/pull/65\r\n\r\nHere is what i have so far, but now i've run into a bug in libclang (well, at least i think its a bug). As said before, the idea is to detect if a property is a class property and generate the matching js code in this case. We use {{clang_Cursor_getObjCPropertyAttributes}} to read the attributes defined on a property. The thing is, as soon as the property contains the {{class}} attribute this function will always return {{CXObjCPropertyAttr_noattr}}. Meaning we have no way to detect if a property is a class property or not. Any ideas how to workaround this are greatly appreciated :)", "updateAuthor": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-08-31T20:48:02.000+0000", "updated": "2016-08-31T20:50:39.000+0000" }, { "id": "395155", "author": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "body": "*sigh* Turns out the rpath build setting was hardcoded to the Xcode 7 toolchain directory and therefore loading the wrong version of libclang causing this unexpected behaviour. Changed it to use the currently selected Xcode version using {{$(DEVELOPER_DIR)}}, works like a charm now. PR updated and ready for review, [~hansknoechel]\r\n\r\nPR: https://github.com/appcelerator/hyperloop.next/pull/65\r\nPR (1.2.X): https://github.com/appcelerator/hyperloop.next/pull/66", "updateAuthor": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-09-01T23:13:11.000+0000", "updated": "2016-09-02T12:58:58.000+0000" }, { "id": "395213", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Ok, so the PR works. However, we now cannot use the known syntax {{UIColor.redColor()}} anymore, only {{UIColor.redColor}} (property instead of method). I see this as a breaking change in Hyperloop, so we should be very cautious integrating is change. If possible, couldn't we \"just\" support both and generate a util-method that creates both the JS method and property? Thoughts?", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-09-02T17:21:28.000+0000", "updated": "2016-09-02T17:22:00.000+0000" }, { "id": "395214", "author": { "name": "jhaynie", "key": "jhaynie", "displayName": "Jeff Haynie", "active": false, "timeZone": "America/Los_Angeles" }, "body": "we should support both class and instance properties. both are legal in JS", "updateAuthor": { "name": "jhaynie", "key": "jhaynie", "displayName": "Jeff Haynie", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-09-02T17:25:38.000+0000", "updated": "2016-09-02T17:25:38.000+0000" }, { "id": "395350", "author": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "body": "The PR does exactly that. I compared with the normal instance property UILabel.text today and this property works exactly the same. You can use {{label.text}} but not {{label.text()}}. As Hans said this is a breaking change in the UIColor api (and other classes that switched to class properties) on our side because of the way objc properties work. Through the property synthesize process in objc nothing changes as the getter/setter methods replace the removed class methods. In JS we can only either use the property or the method but not both.\r\n\r\nI'm currently looking into wether we could improve the usage detection so using {{UIColor.redColor()}} would cause the method to be generated and {{UIColor.redColor}} would trigger the property to be generated.", "updateAuthor": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-09-05T18:42:21.000+0000", "updated": "2016-09-05T18:42:21.000+0000" }, { "id": "395521", "author": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "body": "Ok, for now i updated the [1.2.X PR|https://github.com/appcelerator/hyperloop.next/pull/66] with a simple but not really elegant workaround to maintain api compatibility. We just check against a list of predefined properties (all that are new in iOS 10 because of the {{UIKIT_DEFINE_AS_PROPERTIES}} and {{FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8)}} macros) and generate the getter method rather than the property if it is in this list.\r\n\r\nI'm not really happy with this solution as we would have to maintain the list of properties if anything changes in future iOS SDKs (Script to detect properties affected by the macros: https://gist.github.com/janvennemann/380dde99ef9aa96c6d4a990bee520642). However, there is currently no other way to determine which properties are generated because of those two macros.\r\n\r\nReferring to my last comment, we could detect if someone uses {{UIColor.redColor()}} or {{UIColor.redColor}} and then either generate the appropriate method or property. Using the method and property simultaneously could result in a build error stating to use either of them but not both. The question is if we want to invest more time on this or just remove the workaround in a future version of Hyperloop and introduce the new api based on properties?\r\n", "updateAuthor": { "name": "jvennemann", "key": "jvennemann", "displayName": "Jan Vennemann", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-09-07T16:57:19.000+0000", "updated": "2016-09-07T16:58:08.000+0000" }, { "id": "395558", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~jvennemann] [~hansknoechel] Ok so I spoke with Ingo. We have agreed to go ahead with this PR for the sdk 5.5.0 release. And the proposal is to remove the workaround in Hyperloop 2.0.0 (Ti SDK 6.0.0) and introduce the new api based on properties. So let's get started on testing this PR asap and get a 1.2.7 up.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-09-08T00:49:57.000+0000", "updated": "2016-09-08T00:49:57.000+0000" }, { "id": "395567", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Did a simple FT. For this to work, if you have 2 Xcodes installed, please remember to {{sudo xcode-select --switch /Applications/Xcode-GM.app}} before doing a {{./build.sh}}\r\nAfter you install the built module,\r\nif you do *appc run -p ios -I 10.0* on hyperloop-examples, it works flawlessly.\r\nHowever, if you do *appc run -p ios -I 9.3* on hyperloop-examples, it will fail with {{[ERROR] Unable to find Info.plist in root of specified app path: /Users/kiat/titaniumModules/hyperloop-examples/build/iphone/build/Products/Debug-iphonesimulator/Hyperloop_Sample.app/Info.plist}}\r\nAnd it's true, it's missing. weird!\r\n\r\nHere is why. Hyperloop metabase generation is entirely dependent on the pre-selected Xcode. It's not dependent on the {{-I 10.0}} flag. Here are the rules for Hyperloop to work in the scenario where you have 2 Xcodes existing.\r\n1. {{sudo xcode-select --switch /Applications/Xcode-GM.app}} followed by {{appc run -p ios -I 10.0}}\r\n2. {{sudo xcode-select --switch /Applications/Xcode.app}} followed by {{appc run -p ios -I 9.3}}\r\nIf you mix up this combination, the build will fail with various types of errors, such as the missing info.plist.\r\n\r\nI am ok to put this in the release notes as \"how to use hyperloop if you have 2 versions of Xcode installed\" if we can't fix this in the short time we have. (considering QE still needs to test this)\r\n", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-09-08T03:49:49.000+0000", "updated": "2016-09-08T04:04:29.000+0000" }, { "id": "395668", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "PR approved & merged! [~jvennemann] Please file an own ticket for the bad-access crashes when using classes in a certain edge-case scenario. Thanks!", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-09-09T13:59:07.000+0000", "updated": "2016-09-09T13:59:07.000+0000" }, { "id": "396238", "author": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Verified fixed, using:\r\n\r\nMacOS 10.12 (16A313a)\r\nStudio 4.7.1.201609100950\r\nTi SDK 5.5.0.GA\r\nAppc NPM 4.2.7\r\nAppc CLI 5.5.0\r\nAlloy 1.9.2\r\nXcode 8.0 (8A218a)\r\n\r\nUIColor type properties can be used via the {{UIColor.Color()}} methods with Xcode 8 GA without error. Accessing the properties by actual instance properties {{UIColor.Color}} fails, but that should be covered in Hyperloop 2.0.0, as Kiat mentioned above. Tested using the provided sample code as well as using the UIColor methods in other test apps.", "updateAuthor": { "name": "ewieber", "key": "ewieber", "displayName": "Eric Wieber", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-09-15T17:26:37.000+0000", "updated": "2016-09-15T17:26:37.000+0000" } ], "maxResults": 14, "total": 14, "startAt": 0 } } }