Accessing remote data

With TKDataSource it is easy to utilize data comming from remote sources, for example web services. To do this you should call the loadDataFromURL:dataFormat:rootItemKeyPath:completion: method like demonstrated below:

TKChart *chart = [[TKChart alloc] initWithFrame:self.view.bounds];
chart.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:chart];

NSString *url = @"http://www.telerik.com/docs/default-source/ui-for-ios/weather.json?sfvrsn=2";
[self.dataSource loadDataFromURL:url dataFormat:TKDataSourceDataFormatJSON rootItemKeyPath:@"dayList" completion:^(NSError *error) {

    if (error) {
        NSLog(@"Can't connect with the server");
        return;
    }

    [self.dataSource.settings.chart createSeries:^TKChartSeries *(TKDataSourceGroup *group) {
        TKChartSeries *series = nil;
        if ([group.valueKey isEqualToString:@"clouds"]) {
            series = [TKChartColumnSeries new];
            series.yAxis = [[TKChartNumericAxis alloc] initWithMinimum:@0 andMaximum:@100];
            series.yAxis.title = @"clouds";
            series.yAxis.style.titleStyle.rotationAngle = M_PI_2;
        }
        else {
            series = [TKChartLineSeries new];
            series.yAxis = [[TKChartNumericAxis alloc] initWithMinimum:@-10 andMaximum:@30];
            if ([group.valueKey isEqualToString:@"temp.min"]) {
                series.yAxis.position = TKChartAxisPositionRight;
                series.yAxis.title = @"temperature";
                series.yAxis.style.titleStyle.rotationAngle = M_PI_2;
                [chart addAxis:series.yAxis];
            }
        }
        return series;
    }];

    [self.dataSource map:^id(id item) {
        NSTimeInterval interval = [[item valueForKey:@"dateTime"] doubleValue];
        NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
        [item setValue:date forKey:@"dateTime"];
        return item;
    }];

    self.dataSource.valueKey = @"humidity";

    NSArray *items = self.dataSource.items;
    self.dataSource.itemSource = @[ [[TKDataSourceGroup alloc] initWithItems:items valueKey:@"clouds" displayKey:@"dateTime"],
                                    [[TKDataSourceGroup alloc] initWithItems:items valueKey:@"temp.min" displayKey:@"dateTime"],
                                    [[TKDataSourceGroup alloc] initWithItems:items valueKey:@"temp.max" displayKey:@"dateTime"] ];
    chart.dataSource = self.dataSource;

    NSDateFormatter *formatter = [NSDateFormatter new];
    formatter.dateFormat = @"dd";
    TKChartDateTimeAxis *xAxis = (TKChartDateTimeAxis*)chart.xAxis;
    xAxis.majorTickInterval = 1;
    xAxis.plotMode = TKChartAxisPlotModeBetweenTicks;
    xAxis.labelFormatter = formatter;
    xAxis.title = @"date";
    xAxis.minorTickIntervalUnit = TKChartDateTimeAxisIntervalUnitDays;
}];
let chart = TKChart(frame: self.view.bounds)
chart.autoresizingMask = UIViewAutoresizing(rawValue: ~UIViewAutoresizing().rawValue)
self.view.addSubview(chart)

let url = "http://www.telerik.com/docs/default-source/ui-for-ios/weather.json?sfvrsn=2"
dataSource.loadData(fromURL: url, dataFormat: TKDataSourceDataFormat.JSON, rootItemKeyPath: "dayList") { (err: Error?) -> Void in

    if err != nil {
        print("Can't connect with the server!")
        return
    }

    self.dataSource.settings.chart.createSeries { (group: TKDataSourceGroup?) -> TKChartSeries! in
        let series:TKChartSeries
        if group!.valueKey == "clouds" {
            series = TKChartColumnSeries()
            series.yAxis = TKChartNumericAxis(minimum: 0, andMaximum: 100)
            series.yAxis!.title = "clouds"
            series.yAxis!.style.titleStyle.rotationAngle = CGFloat(M_PI_2);
        }
        else {
            series = TKChartLineSeries()
            series.yAxis = TKChartNumericAxis(minimum: -10, andMaximum: 30)
            if group!.valueKey == "temp.min" {
                series.yAxis!.position = TKChartAxisPosition.right
                series.yAxis!.title = "temperature"
                series.yAxis!.style.titleStyle.rotationAngle = CGFloat(M_PI_2);
                chart.add(series.yAxis!)
            }
        }
        return series
    }

    self.dataSource.map {
        let interval = ($0 as AnyObject).value(forKey: "dateTime") as! TimeInterval
        let date = Date(timeIntervalSince1970: interval)
        ($0 as AnyObject).setValue(date, forKey: "dateTime")
        return $0
    }

    let items = self.dataSource.items
    self.dataSource.itemSource = [TKDataSourceGroup(items: items, valueKey: "clouds", displayKey: "dateTime"),
        TKDataSourceGroup(items: items, valueKey: "temp.min", displayKey: "dateTime"),
        TKDataSourceGroup(items: items, valueKey: "temp.max", displayKey: "dateTime")]

    chart.dataSource = self.dataSource

    let formatter = DateFormatter()
    formatter.dateFormat = "dd"
    let xAxis:TKChartDateTimeAxis = chart.xAxis as! TKChartDateTimeAxis
    xAxis.majorTickInterval = 1
    xAxis.setPlotMode(TKChartAxisPlotMode.betweenTicks)
    xAxis.labelFormatter = formatter
    xAxis.minorTickIntervalUnit = TKChartDateTimeAxisIntervalUnit.days
    xAxis.title = "date"
    xAxis.minorTickIntervalUnit = TKChartDateTimeAxisIntervalUnit.days
}
var chart = new TKChart (this.View.Bounds);
chart.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
this.View.Add (chart);

string url = "http://www.telerik.com/docs/default-source/ui-for-ios/weather.json?sfvrsn=2";
dataSource.LoadDataFromURL (url, TKDataSourceDataFormat.JSON, "dayList", (NSError err) => {
    if (err != null) {
        Console.WriteLine("Can't connect with the server!");
        return;
    }

    dataSource.Settings.Chart.CreateSeries((TKDataSourceGroup group) => {
        TKChartSeries series = null;
        if (group.ValueKey == "clouds") {
            series = new TKChartColumnSeries();
            series.YAxis = new TKChartNumericAxis(NSObject.FromObject(0), NSObject.FromObject(100));
            series.YAxis.Title = "clouds";
            series.YAxis.Style.TitleStyle.RotationAngle = (float)Math.PI/2.0f;
        }
        else {
            series = new TKChartLineSeries();
            series.YAxis = new TKChartNumericAxis(NSObject.FromObject(-10), NSObject.FromObject(30));
            if (group.ValueKey == "temp.min") {
                series.YAxis.Position = TKChartAxisPosition.Right;
                series.YAxis.Title = "temperature";
                series.YAxis.Style.TitleStyle.RotationAngle = (float)Math.PI/2.0f;
                chart.AddAxis(series.YAxis);
            }
        }
        return series;
    });

    dataSource.Map((NSObject item) => {
        double interval = ((NSNumber)item.ValueForKey(new NSString("dateTime"))).DoubleValue;
        NSDate date = NSDate.FromTimeIntervalSince1970(interval);
        item.SetValueForKey(date, new NSString("dateTime"));
        return item;
    });

    NSObject[] items = this.dataSource.Items;
    NSMutableArray newItems = new NSMutableArray();
    newItems.Add(new TKDataSourceGroup(items, "clouds", "dateTime"));
    newItems.Add(new TKDataSourceGroup(items, "temp.min", "dateTime"));
    newItems.Add(new TKDataSourceGroup(items, "temp.max", "dateTime"));
    dataSource.ItemSource = newItems;

    chart.DataSource = dataSource;

    var formatter = new NSDateFormatter();
    formatter.DateFormat = "dd";
    TKChartDateTimeAxis xAxis = (TKChartDateTimeAxis)chart.XAxis;
    xAxis.MajorTickInterval = 1;
    xAxis.PlotMode = TKChartAxisPlotMode.BetweenTicks;
    xAxis.LabelFormatter = formatter;
    xAxis.Title = "date";
    xAxis.MinorTickIntervalUnit = TKChartDateTimeAxisIntervalUnit.Days;
});

The code above downloads a JSON formatted data from the specified web service, sets the valueKey property and presents the result in TKChart.

Authenticating

In some cases the data comming from a remote source is protected. In such scenarios you should inherit a class from TKDataSource and override the appropriate NSURLConnectionDelegate method. TKDataSource supports all authentication modes supported by NSURLConnection. Further information about authentication modes is available in Apple online documentation.

The following code demonstrates the usage of basic authenticaion with TKDataSource:

@implementation DataSourceDocsAuth


- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge previousFailureCount] == 0) {
        NSURLCredential *newCredential = [NSURLCredential credentialWithUser:@"USER" password:@"PASSWORD" persistence:NSURLCredentialPersistenceForSession];
        [[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
    }
    else {
        NSLog(@"previous authentication failure");
    }
}

@end
class DataSourceDocsAuth: TKDataSource {

    class MyDataSource: TKDataSource {

        override func connection(_ connection: NSURLConnection, didReceive challenge: URLAuthenticationChallenge) {
            if challenge.previousFailureCount == 0 {
                let credential = URLCredential(user: "USER", password: "PASSWORD", persistence: URLCredential.Persistence.forSession)
                challenge.sender?.use(credential, for: challenge)
            }
            else {
                print("previous authentication failure")
            }
        }
    }
}
public class DataSourceDocsAuth : TKDataSource
{
    public DataSourceDocsAuth ()
    {
    }
    public class MyDataSource: TKDataSource
    {
        [Export ("connection:didReceiveAuthenticationChallenge:")]
        public void ReceivedAuthenticationChallenge (NSUrlConnection connection, NSUrlAuthenticationChallenge challenge) 
        {
            if (challenge.PreviousFailureCount == 0) {
                var credential = new NSUrlCredential ("USER", "PASSWORD", NSUrlCredentialPersistence.ForSession);
                challenge.Sender.UseCredential (credential, challenge);
            }
            else {
                Console.WriteLine("previous authentication failure");
            }
        }
    }
}