DataSource: Getting Started

This quick start tutorial demonstrates how to create a simple iOS application with TKDataSource.

Prerequisites

This article assumes that you have followed the Downloading UI for iOS, Installing UI for iOS and Setting Up the project steps from the common Getting Started article.

Setting up TKDataSource

Now that our project is created and the TelerikUI.framework is added, we can start referencing and using the TelerikUI types:

Open your ViewController.m file and add a reference to the chart header file:

#import <TelerikUI/TelerikUI.h>

Note that starting with Xcode 6 Apple doesn't generate the precompiled headers file automatically. That is why you should add import the UIKit framework before importing TelerikUI:

#import <UIKit/UIKit.h>

If you are writing Swift, add the same line in your bridging header.

If you are using Xamarin, add a reference to TelerikUI.dll in your project and use the using directive:

using TelerikUI;

The simplest way to use TKDataSource is to initialize it with an array. The following code creates a new instance of TKDataSource and loads it with a numeric array:

self.dataSource = [[TKDataSource alloc] initWithArray:@[ @10, @5, @12, @7, @44 ]];
dataSource = TKDataSource(array: [ 10, 5, 12, 7, 44 ])
dataSource = new TKDataSource (ArrayWithObjects(new object [] { 10, 5, 12, 7, 44 }), null);



TKDataSource supports a full range of data shaping operations including filtering, sorting and grouping. In the code snippet below, we first filter the numbers smaller than 5, then sort the rest, group the sorted values depending on whether they are even or odd, multiply every value by 10 and finally find the max value:

// filter all values less or equal to 5
[self.dataSource filter:^BOOL(id item) { return [item integerValue] > 5; }];

// sort ascending
[self.dataSource sort:^NSComparisonResult(id obj1, id obj2) {
    NSInteger a = [obj1 integerValue];
    NSInteger b = [obj2 integerValue];
    if (a<b) { return NSOrderedDescending; }
    else if (a>b) { return NSOrderedAscending; }
    return NSOrderedSame;
}];

// group odd/even values
[self.dataSource group:^id(id item) { return @([item integerValue] % 2 == 0); }];

// multiply every value * 10
[self.dataSource map:^id(id item) { return @([item integerValue] * 10); }];

// find the max value
NSNumber *maxValue = [self.dataSource reduce:@(0) with:^id(id item, id value) {
    if ([item integerValue] > [value integerValue]) {
        return item;
    }
    return value;
}];
// filter all values less or equal to 5

dataSource!.filter { (i:Any) -> Bool in
    return (i as! NSNumber).int32Value > 5
} 

// sort ascending
dataSource!.sort {
    let a = $0 as! Int
    let b = $1 as! Int
    if a<b { return ComparisonResult.orderedDescending }
    else if a>b { return ComparisonResult.orderedAscending }
    return ComparisonResult.orderedSame
}

// group odd/even values
dataSource!.group { ($0 as! Int) % 2 }

// multiply every value * 10
dataSource!.map { ($0 as! Int) * 10 }

// find the max value
let maxValue = dataSource!.reduce(0) {
    if $0 as! Int > $1 as! Int {
        return $0
    }
    return $1
} as! Int
// filter all values less or equal to 5
dataSource.Filter ((NSObject item) => {
    return ((NSNumber)item).NIntValue > 5;
});

// sort ascending
dataSource.Sort ((NSObject obj1, NSObject obj2) => {
    nint a = ((NSNumber)obj1).NIntValue;
    nint b = ((NSNumber)obj2).NIntValue;
    if (a<b) return NSComparisonResult.Descending; 
    else if (a>b) return NSComparisonResult.Ascending;
    return NSComparisonResult.Same;
});

// group odd/even values
dataSource.Group ((NSObject item) => {
    return NSObject.FromObject(((NSNumber)item).NIntValue % 2 == 0);
});

// multiply every value * 10
dataSource.Map ((NSObject item) => {
    return NSObject.FromObject(((NSNumber)item).NIntValue * 10);
});

// find the max value
NSObject maxValue = dataSource.Reduce (NSObject.FromObject(0), (NSObject item, NSObject value) => {
    if (((NSNumber)item).NIntValue > ((NSNumber)value).NIntValue) 
        return item;
    return value;
});



TKDataSource is an independent component and you can use it without connecting it to a UI control. To show the result just iterate the items:

// output everything to the console
[self.dataSource enumerate:^(id item) {
    if ([item isKindOfClass:[TKDataSourceGroup class]]) {
        TKDataSourceGroup *group = item;
        NSLog(@"group: %@", group.key);
    }
    else {
        NSLog(@"%d", (int)[item integerValue]);
    }
}];
// output everything to the console
dataSource!.enumerate {
    if ($0 as AnyObject).isKind(of: TKDataSourceGroup.self) {
        let group = $0 as! TKDataSourceGroup
        print("group: \(group.key)")
    }
    else {
        print("\($0)")
    }
}
// output everything to the console
dataSource.Enumerate ((NSObject item) => {
    if (item.IsKindOfClass(new ObjCRuntime.Class(typeof(TKDataSourceGroup)))) {
        TKDataSourceGroup group = (TKDataSourceGroup)item;
        Console.WriteLine("group: {0}", group.Key);
    }
    else {
        Console.WriteLine("{0}", ((NSNumber)item).NIntValue);
    }
});



Or, you can create a table view and set its data source property:

// bind with a table view
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
tableView.dataSource = self.dataSource;
[self.view addSubview:tableView];
// bind with a table view
let tableView = UITableView(frame: self.view.bounds)
tableView.dataSource = dataSource
tableView.autoresizingMask = UIViewAutoresizing(rawValue:~UIViewAutoresizing().rawValue)
self.view.addSubview(tableView)
// bind with a table view
var tableView = new UITableView (this.View.Bounds);
tableView.DataSource = dataSource;
this.View.AddSubview (tableView);

Note that the dataSource property of UITableView is weak and you should assign the dataSource instance to a class variable in order to persist its value!



Here is the full code of this example:

@interface DataSourceGettingStarted ()

@property (nonatomic, strong) TKDataSource *dataSource;

@end

@implementation DataSourceGettingStarted

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.title = @"Getting started";

    self.dataSource = [[TKDataSource alloc] initWithArray:@[ @10, @5, @12, @7, @44 ]];

    // filter all values less or equal to 5
    [self.dataSource filter:^BOOL(id item) { return [item integerValue] > 5; }];

    // sort ascending
    [self.dataSource sort:^NSComparisonResult(id obj1, id obj2) {
        NSInteger a = [obj1 integerValue];
        NSInteger b = [obj2 integerValue];
        if (a<b) { return NSOrderedDescending; }
        else if (a>b) { return NSOrderedAscending; }
        return NSOrderedSame;
    }];

    // group odd/even values
    [self.dataSource group:^id(id item) { return @([item integerValue] % 2 == 0); }];

    // multiply every value * 10
    [self.dataSource map:^id(id item) { return @([item integerValue] * 10); }];

    // find the max value
    NSNumber *maxValue = [self.dataSource reduce:@(0) with:^id(id item, id value) {
        if ([item integerValue] > [value integerValue]) {
            return item;
        }
        return value;
    }];

    NSLog(@"the max value is: %@", maxValue);

    // output everything to the console
    [self.dataSource enumerate:^(id item) {
        if ([item isKindOfClass:[TKDataSourceGroup class]]) {
            TKDataSourceGroup *group = item;
            NSLog(@"group: %@", group.key);
        }
        else {
            NSLog(@"%d", (int)[item integerValue]);
        }
    }];

    // bind with a table view
    UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    tableView.dataSource = self.dataSource;
    [self.view addSubview:tableView];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
class DataSourceGettingStarted: TKExamplesExampleViewController {

    var dataSource: TKDataSource?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.title = "Getting started"

        dataSource = TKDataSource(array: [ 10, 5, 12, 7, 44 ])

        // filter all values less or equal to 5

        dataSource!.filter { (i:Any) -> Bool in
            return (i as! NSNumber).int32Value > 5
        } 

        // sort ascending
        dataSource!.sort {
            let a = $0 as! Int
            let b = $1 as! Int
            if a<b { return ComparisonResult.orderedDescending }
            else if a>b { return ComparisonResult.orderedAscending }
            return ComparisonResult.orderedSame
        }

        // group odd/even values
        dataSource!.group { ($0 as! Int) % 2 }

        // multiply every value * 10
        dataSource!.map { ($0 as! Int) * 10 }

        // find the max value
        let maxValue = dataSource!.reduce(0) {
            if $0 as! Int > $1 as! Int {
                return $0
            }
            return $1
        } as! Int

        print("the max value is: \(maxValue)")

        // output everything to the console
        dataSource!.enumerate {
            if ($0 as AnyObject).isKind(of: TKDataSourceGroup.self) {
                let group = $0 as! TKDataSourceGroup
                print("group: \(group.key)")
            }
            else {
                print("\($0)")
            }
        }

        // bind with a table view
        let tableView = UITableView(frame: self.view.bounds)
        tableView.dataSource = dataSource
        tableView.autoresizingMask = UIViewAutoresizing(rawValue:~UIViewAutoresizing().rawValue)
        self.view.addSubview(tableView)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
[Register("DataSourceGettingStarted")]
public class DataSourceGettingStarted: XamarinExampleViewController
{
    TKDataSource dataSource;

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        dataSource = new TKDataSource (ArrayWithObjects(new object [] { 10, 5, 12, 7, 44 }), null);

        // filter all values less or equal to 5
        dataSource.Filter ((NSObject item) => {
            return ((NSNumber)item).NIntValue > 5;
        });

        // sort ascending
        dataSource.Sort ((NSObject obj1, NSObject obj2) => {
            nint a = ((NSNumber)obj1).NIntValue;
            nint b = ((NSNumber)obj2).NIntValue;
            if (a<b) return NSComparisonResult.Descending; 
            else if (a>b) return NSComparisonResult.Ascending;
            return NSComparisonResult.Same;
        });

        // group odd/even values
        dataSource.Group ((NSObject item) => {
            return NSObject.FromObject(((NSNumber)item).NIntValue % 2 == 0);
        });

        // multiply every value * 10
        dataSource.Map ((NSObject item) => {
            return NSObject.FromObject(((NSNumber)item).NIntValue * 10);
        });

        // find the max value
        NSObject maxValue = dataSource.Reduce (NSObject.FromObject(0), (NSObject item, NSObject value) => {
            if (((NSNumber)item).NIntValue > ((NSNumber)value).NIntValue) 
                return item;
            return value;
        });

        Console.WriteLine ("the max value is: {0}", ((NSNumber)maxValue).NIntValue);

        // output everything to the console
        dataSource.Enumerate ((NSObject item) => {
            if (item.IsKindOfClass(new ObjCRuntime.Class(typeof(TKDataSourceGroup)))) {
                TKDataSourceGroup group = (TKDataSourceGroup)item;
                Console.WriteLine("group: {0}", group.Key);
            }
            else {
                Console.WriteLine("{0}", ((NSNumber)item).NIntValue);
            }
        });

        // bind with a table view
        var tableView = new UITableView (this.View.Bounds);
        tableView.DataSource = dataSource;
        this.View.AddSubview (tableView);

    }

    NSObject[] ArrayWithObjects(object[] objects)
    {
        List<NSObject> array = new List<NSObject>();
        for (int i = 0; i<objects.Length; i++) {
            array.Add (NSObject.FromObject (objects [i]));
        }
        return array.ToArray();
    }
}



You can easily switch the UI control used to present data coming from TKDataSource. It supports the most common data enabled UI controls, so you can use it the same way with UICollectionView, TKChart, TKListView, or TKCalendar. The following article demonstates how to initialize and customize the UI controls supported by TKDataSource:
Binding with UI controls

TKDataSource supports also different data inputs. This article demonstrates how to load data comming from files or a web service.
Loading with data

Data shaping operations are described in detail in this article:
Data shaping operations