public override NSView GetViewForItem(NSTableView tableView, NSTableColumn tableColumn, nint row) { string identifier = tableColumn.Identifier; NSTableCellView cellView = (NSTableCellView)tableView.MakeView(identifier, this); Quake quake = quakesSource [(int)row]; if (identifier == ColumnIdentifierPlace) { cellView.TextField.StringValue = quake.Location; } else if (identifier == ColumnIdentifierTime) { cellView.TextField.ObjectValue = quake.Date; } else if (identifier == ColumnIdentifierMagnitude) { cellView.TextField.ObjectValue = quake.Magnitude; } return(cellView); }
void FetchQuakes(object sender, EventArgs e) { fetchQuakesButton.Enabled = false; var jsonURL = new NSUrl("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson"); var session = NSUrlSession.FromConfiguration(NSUrlSessionConfiguration.EphemeralSessionConfiguration); NSUrlSessionTask task = session.CreateDataTask(jsonURL, (data, response, error) => { if (data == null) { Console.WriteLine("Error connecting: {0}", error.LocalizedDescription); return; } NSError anyError; NSManagedObjectContext taskContext = CreatePrivateQueueContext(out anyError); var jsonDictionary = NSJsonSerialization.Deserialize(data, NSJsonReadingOptions.AllowFragments, out anyError); if (jsonDictionary == null) { Console.WriteLine("Error creating JSON dictionary: {0}", anyError.LocalizedDescription); return; } var featuresArray = (NSArray)jsonDictionary.ValueForKey((NSString)"features"); int totalFeatureCount = (int)featuresArray.Count; int numBatches = totalFeatureCount / BatchSize; numBatches += totalFeatureCount % BatchSize > 0 ? 1 : 0; for (int batchNumber = 0; batchNumber < numBatches; batchNumber++) { int rangeStart = batchNumber * BatchSize; int rangeLength = Math.Min(BatchSize, totalFeatureCount - batchNumber * BatchSize); NSArray featuresBatchArray = featuresArray.SubarrayWithRange(new NSRange(rangeStart, rangeLength)); // Create a request to fetch existing quakes with the same codes as those in the JSON data. // Existing quakes will be updated with new data; if there isn't a match, then create a new quake to represent the event. NSFetchRequest matchingQuakeRequest = NSFetchRequest.FromEntityName("Quake"); // Get the codes for each of the features and store them in an array. NSArray codesDump = (NSArray)featuresBatchArray.ValueForKeyPath((NSString)"properties.code"); matchingQuakeRequest.Predicate = NSPredicate.FromFormat("code in %@", codesDump); var rawFetch = taskContext.ExecuteFetchRequest(matchingQuakeRequest, out anyError); Quake[] allMatchingQuakes = Array.ConvertAll(rawFetch, item => (Quake)item); NSString[] codes = NSArray.FromArray <NSString> (codesDump); for (int k = 0; k < codes.Length; k++) { var code = codes [k]; var matchingQuakes = allMatchingQuakes.Where(q => q.Code == code).ToArray <Quake> (); Quake quake = null; int matchingLength = matchingQuakes.Length; switch (matchingLength) { case 0: //Insert new item quake = (Quake)NSEntityDescription.InsertNewObjectForEntityForName("Quake", taskContext); break; case 1: //Update existing item quake = matchingQuakes [0]; break; default: //Remove duplicates for (int i = 1; i < matchingQuakes.Length; i++) { taskContext.DeleteObject(matchingQuakes [i]); } quake = matchingQuakes [0]; break; } var result = featuresBatchArray.GetItem <NSDictionary> ((nuint)k); var quakeDictionary = (NSDictionary)result.ObjectForKey((NSString)"properties"); quake.UpdateFromDictionary(quakeDictionary); } if (!taskContext.Save(out anyError)) { Console.WriteLine("Error saving batch: {0}", anyError.LocalizedDescription); return; } taskContext.Reset(); } // Bounce back to the main queue to reload the table view and reenable the fetch button. NSOperationQueue.MainQueue.AddOperation(() => { ReloadTableView(); fetchQuakesButton.Enabled = true; }); }); task.Resume(); }