Charts: Swift 4, Obj-C compatibility, access control, naming, and Swift convention

Created on 19 Jul 2017  Â·  8Comments  Â·  Source: danielgindi/Charts

With a new major release of Swift, it seems as good a time as any to reevaluate some key aspects of Charts. First the changes that Swift 4 brings requires no changes to the Charts codebase — outside of some naming that the migrator takes care of.

Objective-C Compatibility

The biggest thing I'd like to see is a move away from Objective-C compatibility. This is a huge change, but it would allow us to get rid of all the NSObject subclasses and in many cases replace them with Structs/Enums (e.g. Fill can be rewritten with half the code as an enum with associated values). It could also allow us to turn the Charts data source (ChartData, ChartDataSet, ChartDataEntry) into generic value types which would remove the need for all the casting that's currently required and should improve performance with large data sets, or at the very least, memory usage. At the very least, being able to strictly use Swift convention will drastically reduce the codebase.

My thought is that Charts 4 be the first version to Obj-C drop compatibility, with Charts 3.x only receiving bug fixes. There are many things we can do to make it easier to migrate from, and maintain Charts 3.x (e.g. forbidding the use of isEqual(), using == instead, and providing identical overrides to both methods), but I don't think this post is the place to discuss implementation.

Access Control and Naming

When I first started using Charts, I found it confusing which API to use (e.g. pinchZoomEnabled vs isPinchZoomEnabled). In most — I think all — cases, only one of them is mutable so it's easy to figure out, but it's still an issue. Part of the problem is naming, and the other is access control. Virtually the entire API is public or open, but little, if any, of it actually should be overridable, and many things don't need to be visible to the user. I would like to see a reevaluation of access control, and get rid of internal variables where not necessary (e.g. _pinchZoomEnabled, pinchZoomEnabled, and isPinchZoomEnabled). I would also like to see some function/property renaming to be in line with the Swift API Guidelines.

Swift Convention

There are many areas where it makes sense to adopt some standard Swift protocols like Equatable, Collection (and related), etc. I would like to see more of these implemented. Many algorithms can be simplified to much less code (e.g. many if-else statements can be replaced with min(_,_)/max(_,_), and many loops can be replaced with map, filter, or reduce).

There's a lot here, and as @liuxuan30 points out, we're a bit short handed, but I would be happy do much of the work (especially the move away from Obj-C), but first we need discussion and decisions to be made.

Most helpful comment

My biggest question is: do we still need to maintain backwards compatibility with Obj-C and why?

There are lots of people using swift in their ObjC projects, so we need to support.

All 8 comments

thank you for your thoughts. This is not a simple work. I think we would agree on adopting new swift standard, as long as we can still use Charts in ObjC projects.

But on the other hand, we have experienced from swift 1.2 to 3.x. Honestly it's a little painful that every major release, so many changed in terms of syntax and usage. I wonder if swift 5 would change again, though swift 4 has the least changes so far, looks more stable.

Now our captain @danielgindi has been missing for quite a while :), honestly I haven't been watching swift 4 for some time as well. We may slow down adopting the new swift 4 syntax, as long as the current one is working. You are welcome to contribute, but I am not sure how it goes to be reviewed. So take your time, no pressure.

BTW, can you post any link/guideline about what you said here? So we can have a comprehensive understanding of what are the new rules.

Luckily Swift 4 doesn't introduce many breaking changes to syntax, it's largely the @objc inference which is already taken care of. With regards to usage, nothing changes if we are keeping objc compatibility. My biggest question is: do we still need to maintain backwards compatibility with Obj-C and why? There are many features of Swift we are missing out on that will improve performance, reduce the size of the code base, and make the code easier to read including (from Apple's documentation):

  • Generics
  • Tuples
  • Enumerations w/o raw values or w/associated values
  • Swift structs
  • Swift typealiases
  • variadics
  • Nested types

I've spent a few days making the conversion to only supporting Swift 4 (also rewriting the iOS demos). As you can see, there are a far fewer optionals across the board, and in many spots a lot less code. I haven't dug into most of the class trees yet, but the few that I have seen drastic reductions in code size and readability (Fill.swift is the one I like most so far). So far I've brought the source down to about 10%, and 30% should be easily doable.

There are many base classes that make more sense to be Swift protocols w/extensions, but aren't for compatibility with objc, including (I encourage you to take a look at my fork):

  • Renderer, DataRenderer, BarLineScatterCandleBubbleRenderer, LineScatterCandleBubbleRenderer, AxisRenderer, ShapeRender
  • Marker
  • ValueFormatter, AxisValueFormatter, FillFormatter
  • and more

There are other places where using protocols with associated types remove conditional casting and duplicating ivars with slightly different names, especially in the data model. My first attempt (I say attempt because it affects virtually the entire code base and introducing other things first will ease the transition) at a Swift data model is here. Notice I also used structs, which make more sense to me for the data model, and that the code size dropped by 27 kb. DataSets/ChartData don't require separate properties or casting to access their Entries/DataSets since the associated values allow their values/dataSets properties to take on the type that we want them to be.

I'm hoping for more community discussion on this, but after reading quite a few of the issues, it doesn't seem likely. Perhaps a Swift only version would be better run as a separate project, but that gets a bit messy too.

With regards to links:

My biggest question is: do we still need to maintain backwards compatibility with Obj-C and why?

There are lots of people using swift in their ObjC projects, so we need to support.

They can continue to use the old project for Objective-C and the new project is Swift-only. Even in our Obj-C project, all new code is Swift (its a major project with 900 classes). So we use Swift-only projects all the time and just them from the new Swift code.

This is my thought too. If you have an existing Objective-C project using Charts, you can continue to use Charts 3.x. All new code can and, in most cases, should be written in Swift in which case you can use Charts 4+.

Any bug fixes to the implementation of Charts will in many cases be easily add to 3.x as well, but moving to pure Swift will allow major parts of the framework to be rethought. In some cases this will improve performance, and in almost all cases this will drastically reduce the code base and improve readability allowing for better maintenance of the project.

I believe the best path moving forward is to provide bug fixes for 3.x, make 4.x Swift only, and rethink the implementation for 5+, and with the release of Charts 5, remove support for 3.x.

Unless there is sold proof there is a huge win in terms of performance in swift only mode, I don't think we would abandon objc users before Apple do so. Making different versions/branches to maintain would require much more man power and honestly, this is what we need the most, as a free open source library.

I have a question about Objective-C compatibility. My Mac app is Objective-C only right now and my iOS app is dual Objective-C and Swift.

If I write a view controller in Swift in my macOS app, would that be good enough to incorporate a Swift only version of this charting framework to display it in the view? Or does moving to Swift only mean that I can't have any Objective-C code in my project? Sorry if this is a dumb question. I've used Swift in my iOS app interchanged with Objective-C with no problem. But those were just some Swift source code files, not compiled as a framework.

@brendand This is the wrong place to ask this. This is the right place.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Bharati555 picture Bharati555  Â·  4Comments

kwstasna picture kwstasna  Â·  3Comments

kirti0525 picture kirti0525  Â·  3Comments

guoyutaog picture guoyutaog  Â·  3Comments

Shunshine07 picture Shunshine07  Â·  3Comments