Search Your Question

Showing posts with label Globant. Show all posts
Showing posts with label Globant. Show all posts

What are best approach to implement if large data is coming from core data and show data on tableview?

Ans : 

Use NSFetchResultsController : A controller that you use to manage the results of a Core Data fetch request and to display data to the user.

If we have very large data in database and we want all data to show in tableview, then we have to write some extra code on core data fetch request as fetching data will stuck UI.
Then we can use NSFetchResultsController as it has ability to fetch data from memory in batches. So data coming in batch when we scroll tableview and saved in cache.

We have to make property of type NSFetchResultsController :

- (NSFetchedResultsController *)fetchedResultsController {
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
        entityForName:@"FailedBankInfo" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
        initWithKey:@"details.closeDate" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
    [fetchRequest setFetchBatchSize:20];
    NSFetchedResultsController *theFetchedResultsController =
        [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
            managedObjectContext:managedObjectContext sectionNameKeyPath:nil
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;
    return _fetchedResultsController;

and in ViewDidLoad :

- (void)viewDidLoad {
    [super viewDidLoad];
    NSError *error;
 if (![[self fetchedResultsController] performFetch:&error]) {
  // Update to handle the error appropriately.
  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  exit(-1);  // Fail
    self.title = @"Failed Banks";

We get data in numberOfRowInSection :
id  sectionInfo =
        [[_fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];

We get data in cellForRowAtIndexPath :
FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];

We also have to write FetchResultsControllerDelegate methods as it is as at apple provide at end of ViewController's code.

Enjoy lazy loading data...

Tutorial : Ray Wanderlich

Different task available in NSURLSession

Ans : 

NSURLSession   :       The NSURLSession class and related classes provide an API for downloading data from and uploading data to endpoints indicated by URLs. Your app can also use this API to perform background downloads when your app isn’t running or, in iOS, while your app is suspended.
It is replacement of NSURLConnection from iOS 7.

Types of URL Sessions :

  1. default sessions: behaviour like NSURLConnection 
  2. ephemeral sessions: not cache any content to disk 
  3. download sessions: store the result in file and transferring data even when app is suspended, exits or crashes
Based on above sessions, developers can schedule three types of tasks: 

  1. data tasks: retrieve data to memory 
  2. download tasks: download file to disk 
  3. upload tasks: uploading file from disk and receiving response as data in memory 

func httpGet(request: NSURLRequest!, callback: (String, String?) -> Void) {
            var session = NSURLSession.sharedSession()
            var task = session.dataTaskWithRequest(request){
                 (data, response, error) -> Void in
                 if error != nil {
                     callback(“”, error.localizedDescription)
                 } else {
                     var result = NSString(data: data, encoding:
                     callback(result, nil)

How can we store object in user default?

Ans : 

Actually, you will need to archive the custom object into NSData then save it to user defaults and retrieve it from user defaults and unarchive it again. You can archive it like this
let teams = [Team(id: 1, name: "team1", shortname: "t1"), Team(id: 2, name: "team2", shortname: "t2")]

var userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: teams)
userDefaults.set(encodedData, forKey: "teams")
and unarchive it like this
let decoded  = "teams")
let decodedTeams = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Team]
But if you just did that you will get
.Team encodeWithCoder:]: unrecognized selector sent to instance
You will have to make Team conform to NSCoding just like this
class Team: NSObject, NSCoding {
    var id: Int
    var name: String
    var shortname: String

    init(id: Int, name: String, shortname: String) { = id = name
        self.shortname = shortname


    required convenience init(coder aDecoder: NSCoder) {
        let id = aDecoder.decodeInteger(forKey: "id")
        let name = aDecoder.decodeObject(forKey: "name") as! String
        let shortname = aDecoder.decodeObject(forKey: "shortname") as! String
        self.init(id: id, name: name, shortname: shortname)

    func encode(with aCoder: NSCoder) {
        aCoder.encode(id, forKey: "id")
        aCoder.encode(name, forKey: "name")
        aCoder.encode(shortname, forKey: "shortname")