NativeScript / ios-jsc

NativeScript for iOS using JavaScriptCore
http://docs.nativescript.org/runtimes/ios
Apache License 2.0
299 stars 59 forks source link

[bug] MetaData generation from Swift 5 code #1221

Closed NathanaelA closed 4 years ago

NathanaelA commented 4 years ago

Environment Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

Describe the bug Metadata from Swift 5 code seems to be inconsistent; (Please note if you need these as two different bugs, we can split it)

First Metadata issue: https://github.com/nstudio/Charts/blob/16c64db1becf6a3e5574d3e93dfc3c7bfe8273c1/Source/Charts/Charts/ChartViewBase.swift#L160-L171

On Line 160; is a whole new method that I had to create; this method has the Metadata properly generated. I created it so I can proceed; but I would much rather use the library as is; and not have to create silly NativeScript helpers because of metadata generation issues...

On Line 166; this method started without a @objc on it; but IS/WAS still callable by objc. I tried both just adding a @objc and the current @obc(initWithFrame:) neither generate metadata and neither can be called from NativeScript.

Second MetaData issue: This seems to be a relates issue with overriding and hiding above... This metadata (data) https://github.com/nstudio/Charts/blob/16c64db1becf6a3e5574d3e93dfc3c7bfe8273c1/Source/Charts/Charts/ChartViewBase.swift#L220 does not get created properly on the object because apparently the metadata system gets confused by this statement... https://github.com/nstudio/Charts/blob/master/Source/Charts/Interfaces/ChartDataProvider.swift#L36

Because the metadata shows it as readonly property. So even though ChartViewBase implements ChartDataProvider protocol, it's version of data has a setter, the metadata generated does not. Again this property is accessible from objc but not NativeScript.

UPDATE on second issue -- adding @objc to the Data method seems to make it visible to NativeScript properly; however ObjC doesn't need this tag to use it...

To Reproduce Add a simple podfile to your project; and then generate the metadata/typings.
Podfile: pod 'Charts', :git => 'https://github.com/nstudio/Charts', :commit => '024087274344906e72fd7efe4abe77eca7ba983d'

Expected behavior Metadata to be generated and work...

Sample project Just drop the above Podfile in a test app; and generate the meta data. Technically you can delete the :git and :commit and use the original Charts version; but my commit has some additional methods so you can see the differences.

NathanaelA commented 4 years ago

This issue is actually worse than I described. The farther I dig into this; the worse the metadata consistency is. First things first, the 500k generated Charts-Swift.h looks correct. So this appears to be a solely a NativeScript metadata issue; and not a swift issue.

From the Charts-swift.h file:

image

You can obviously see both initWithFrame and initWithRect in the header next to each other; but initWithFrame doesn't show up in the NativeScript metadata... image


Instance Tree from header:

image

image

image

So the basic structure of this object is: UIView -> NSUIView -> ChartViewBase -> BarLineChartViewBase -> LineChartView only some things from UIView and above are showing in the LineChartView. However imporantant things like initWithRect are not visible to LineChartView; in fact I'm having a very hard time figuring out which items will show and which ones don't show. Many items that are exposed as @objc (like init, data, NativeScriptData) are visible at the ChartViewBase meta data, and are accessable from NativeScript. However, they seem to vanish in descendants metadata from NS, but are accessible from ObjC fine.

So doing a let X = LineChartView.alloc().initWithRect(...) will fail. Where let x = ChartViewBase.alloc().initWithRect() will work.

So basically it seems like for me to actually use LineChartView; I'm going to have to create stuff like InitWithRect(rect) { super.init(rect: rect); } on the LineChartView and let Swift pass the values up to the super version of it.

NathanaelA commented 4 years ago

This might be all solved by https://github.com/NativeScript/ios-runtime/pull/1218

I have tried @next on the project and magically the metadata seems to be working... I'll re-open if I find that this doesn't fix everything as I try moving forward...

mbektchiev commented 4 years ago

Yep, it looks like it should have been solved with it.

NathanaelA commented 4 years ago

@mbektchiev - There are still some minor corner case issues, For example the read only data is seen but the read/write version created in the class is not; so the meta data still thinks it is a readonly property and trying to write to it crashes the app. But objc can write to it fine based on all the demo code. So it is a inconsistency.

But overall it solved the vast majority of them. :-D