A .NET for iOS binding by Lucas Teixeira for Charts (now DGCharts) by Daniel Cohen Gindi, inspired by Philipp Jahoda. https://github.com/ChartsOrg/Charts
- Binds DGCharts 5.1.0 shipped as
DGCharts.xcframework: devicearm64, simulatorarm64+x86_64. Apple-silicon simulators work;armv7/i386are gone. - Targets net10.0-ios (.NET 10 SDK, iOS workload 26.5). Built and verified with Xcode 26.6.
- No more
Xamarin.Swift*dependencies. The Swift 5 ABI is stable and the runtime ships with iOS 12.2+. - The native library is delivered as a .NET binding resource package (
iOSCharts.resources.zipnext to the dll in the NuGet), which is whatNoBindingEmbedding=trueproduces. - Breaking changes from Charts 3.x are upstream's: https://github.com/ChartsOrg/Charts/blob/master/CHANGELOG.md
Charts 5 renamed its Swift protocols, and the C# names follow the Objective-C names, so the old IInterface…
work-around is gone:
| 3.2.x binding | 5.1.0 binding |
|---|---|
IInterfaceChartDataSet / InterfaceChartDataSet |
IChartDataSetProtocol / ChartDataSetProtocol |
IInterfaceLineChartDataSet … |
ILineChartDataSetProtocol … (same for Bar, Bubble, Candle, Pie, Radar, Scatter, LineRadar, …) |
IInterfaceChartValueFormatter / InterfaceChartValueFormatter |
IChartValueFormatter / ChartValueFormatter |
IInterfaceChartAxisValueFormatter |
IChartAxisValueFormatter / ChartAxisValueFormatter |
IInterfaceChartFillFormatter |
IChartFillFormatter / ChartFillFormatter |
IInterfaceChartMarker / InterfaceChartMarker |
IChartMarker / ChartMarker |
IInterfaceChartHighlighter |
IChartHighlighterProtocol / ChartHighlighterProtocol (the class is still ChartHighlighter) |
IInterfaceShapeRenderer |
IShapeRenderer / ShapeRenderer |
ChartRenderer, ChartDataRendererBase, ChartAxisRendererBase classes |
IChartRenderer / IChartDataRenderer protocols; axis renderers derive from NSObject |
ChartFill class + ChartFillType enum |
IChartFill protocol with ChartColorFill, ChartLinearGradientFill, ChartRadialGradientFill, ChartImageFill, ChartLayerFill, ChartEmptyFill |
To implement a protocol in C#, subclass the model class (class MyFormatter : ChartValueFormatter { … }) and
override its members; pass it wherever the I… interface is expected. Constructors take IntPtr-free
NativeHandle handles now.
var entries = Enumerable.Range(0, 8).Select(i => new ChartDataEntry(i, Math.Sin(i) * 10 + 20)).ToArray();
var set = new LineChartDataSet(entries, "sin") { Mode = LineChartMode.CubicBezier };
set.Colors = ChartColorTemplates.Material;
set.ValueFormatter = new MyValueFormatter(); // : ChartValueFormatter
chart.Data = new LineChartData(new IChartDataSetProtocol[] { set });
chart.XAxis.ValueFormatter = new ChartIndexAxisValueFormatter(new[] { "a", "b", "c" });
chart.Delegate = new MyDelegate(); // : ChartViewDelegateRequirements: .NET 10 SDK with the ios workload, Xcode 26.6. When more than one Xcode is installed, point
the .NET SDK at 26.6:
export MD_APPLE_SDK_ROOT=/Applications/Xcode26.6.app
dotnet build -c Release # produces bin/Release/iOSCharts.5.1.0.nupkg../global.json pins the .NET SDK to 10.0.302.
All the hand tweaks the Swift → Objective-C → C# path needs are scripted in tools/:
tools/build-xcframework.sh /path/to/Charts-x.y.zarchives theDGChartsscheme for iOS and the iOS Simulator with Xcode 26.6 and writesDGCharts.xcframeworkhere.tools/sharpie.shruns Objective Sharpie 3.5 onDGCharts-Swift.h. Sharpie's clang cannot read the iOS 26 SDK module map, so the script imports UIKit textually through a wrapper header with-fno-modulesand adds the SDKSubFrameworkssearch path; without that everyCGFloat/BOOLcomes out asNSObject.python3 tools/transform.py <ApiDefinitions.cs> <StructsAndEnums.cs> ApiDefinition.cs Structs.csre-applies the "witchcraft":- a dummy
interface IFoo { }per protocol, soIFoocan be used as a parameter/property type; - every protocol is
[Protocol(Name = "_TtP8DGCharts…_"), Model]+[BaseType(typeof(NSObject))](Sharpie already emits the mangled_TtC8DGCharts…/_TtP8DGCharts…runtime names for the Swift types without an explicit@objc(Name)); - members use the
IFooform for protocol types, classes and protocols adopt protocols in the bareinterface Foo : FooProtocolform. That bare form is what makes bgen inline the members and implementIFooProtocol; with theIform bgen sees only the dummy interface and the class does not implement the protocol at all; - get-only protocol properties that the concrete classes expose as settable get a
set;(data,axisDependency,colors,barData, …), otherwise the copy re-inlined into every subclass hides the settable one of the base class andlineChart.Data = …stops compiling; - the protocol
ChartHighlightershares its Objective-C name with the class, so the C# protocol isChartHighlighterProtocol; - Sharpie's odd protocol member names (
Axis,Y,Rect,DataSet,Entry,DataProvider) become the class member names,chartView:animatorDidStop:becomesChartViewAnimatorDidStop; copyWithZone:(INSCopyingstays),initWithCoder:(bgen adds it forUIViewsubclasses),observeValueForKeyPath:…,[Verify], and thensui*UIKit helper categories are dropped; the in-module Swift extension categories are folded into their classes;NSTextAlignment→UITextAlignment.
- a dummy
dotnet build -c Release, thentools/SmokeTest(a .NET iOS app;dotnet buildit and run on an arm64 simulator) exercises every chart type, formatter/delegate/marker subclasses and the mangled names.
If you got here after googling for a way to bind Swift libraries in Xamarin / .NET for iOS, the steps above are the whole recipe. Feel free to reach out: https://twitter.com/flash3001
Copyright 2016-2026 Lucas Teixeira, Daniel Cohen Gindi & Philipp Jahoda
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.