Ejemplo n.º 1
0
        private void AddEarthquakesToList(List <Earthquake> earthquakes)
        {
            var entity       = NSEntityDescription.EntityForName("Earthquake", managedObjectContext);
            var fetchRequest = new NSFetchRequest();

            fetchRequest.Entity = entity;

            var date     = (NSPropertyDescription)entity.PropertiesByName.ValueForKey(new NSString("date"));
            var location = (NSPropertyDescription)entity.PropertiesByName.ValueForKey(new NSString("location"));

            fetchRequest.PropertiesToFetch = new NSPropertyDescription[] { date, location };
            fetchRequest.ResultType        = NSFetchRequestResultType.DictionaryResultType;

            NSError error;

            foreach (var earthquake in earthquakes)
            {
                var arguments = new NSObject[] { earthquake.Location, earthquake.Date };
                fetchRequest.Predicate = NSPredicate.FromFormat(@"location = %@ AND date = %@", arguments);
                var fetchedItems = NSArray.FromNSObjects(managedObjectContext.ExecuteFetchRequest(fetchRequest, out error));

                if (fetchedItems.Count == 0)
                {
                    if (string.IsNullOrEmpty(entity.Description))
                    {
                        continue;
                    }

                    var managedEarthquake = new ManagedEarthquake(entity, managedObjectContext)
                    {
                        Magnitude   = earthquake.Magnitude,
                        Location    = earthquake.Location,
                        Date        = earthquake.Date,
                        USGSWebLink = earthquake.USGSWebLink,
                        Latitude    = earthquake.Latitude,
                        Longitude   = earthquake.Longitude
                    };

                    managedObjectContext.InsertObject(managedEarthquake);
                }

                var gregorian        = new NSCalendar(NSCalendarType.Gregorian);
                var offsetComponents = new NSDateComponents();
                offsetComponents.Day = -14;                // 14 days back from today
                NSDate twoWeeksAgo = gregorian.DateByAddingComponents(offsetComponents, NSDate.Now, NSCalendarOptions.None);

                // use the same fetchrequest instance but switch back to NSManagedObjectResultType
                fetchRequest.ResultType = NSFetchRequestResultType.ManagedObject;
                fetchRequest.Predicate  = NSPredicate.FromFormat(@"date < %@", new NSObject[] { twoWeeksAgo });

                var olderEarthquakes = NSArray.FromObjects(managedObjectContext.ExecuteFetchRequest(fetchRequest, out error));

                for (int i = 0; i < olderEarthquakes.Count; i++)
                {
                    managedObjectContext.DeleteObject(olderEarthquakes.GetItem <ManagedEarthquake> (i));
                }

                if (managedObjectContext.HasChanges)
                {
                    if (!managedObjectContext.Save(out error))
                    {
                        Console.WriteLine(string.Format("Unresolved error {0}", error.LocalizedDescription));
                    }
                }
            }
        }
Ejemplo n.º 2
0
        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();
        }