斯坦福iOS7 2013-2014秋Assignment 6的一种答案 #6

来源:互联网 发布:和谐万维软件 编辑:程序博客网 时间:2024/06/14 12:51

这篇文章是针对斯坦福iOS7 2013-1014的公开课Assignment 6 Top Regions所进行的解答的第六部分。实在是很抱歉,最近工作太忙了,加上又开始从零开始学习PHP与MySQL(有一起学的可以交流),这部分拖了十几天,不过在接下来的时间我会尽量尽快完成,希望能一起学习提高。路漫漫其修远兮,继续吧!

1 Your application must work identically to last week except that where you are displaying the “top places” (as reported by Flickr), you are going to display the “top regions” in which photos have been taken. You will calculate the most popular regions from the data you gather periodically from the URLforRecentGeoreferencedPhotos. 

本节主要是把TopRegion的数据库在App中展示出来。

首先下载课程里提供的CoreDataTableViewController拖到项目里。然后建立下图所示的UI(如果完成过Assignment 5,可以copy过来基本一样,这里我们只完成iPhone的Storyboard)。


把Top Regions的单元格标识符改为“Region Cell”,新建一个CoreDataTableViewController的子类,并命名为TopRegionsTVC。

然后你只需要让fetchedResultsController(还记得课上讲的把,很简单)来获取数据

- (UITableViewCell *)tableView:(UITableView *)tableView         cellForRowAtIndexPath:(NSIndexPath *)indexPath{    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Region Cell"];    Region *region = [self.fetchedResultsController objectAtIndexPath:indexPath];    cell.textLabel.text = region.name;    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ photographers %@ photos", region.photographerCount, region.photoCount];    return cell;}

然而,怎么连接数据库呢,我们这里通过通知来获得,新建一个跟课上一样的PhotoDatabaseAvailability.h的protocol文件

#define PhotoDatabaseAvailabilityNotification @"PhotoDatabaseAvailabilityNotification"#define PhotoDatabaseAvailabilityContext @"Context"
<span class="s1" style="font-family: Arial, Helvetica, sans-serif;">#define PhotoDatabaseNewDataAvailabilityNotification @</span><span class="s2" style="font-family: Arial, Helvetica, sans-serif;">"PhotoDatabaseNewDataAvailabilityNotification"</span>


在appDelegate中import这个文件并发布通知:

#import "PhotoDatabaseAvailability.h"

- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    ...    [DocumentHelper useDocumentWithOperation:^(UIManagedDocument *document, BOOL success) {        if (success) {            NSDictionary *userInfo = document.managedObjectContext ? @{ PhotoDatabaseAvailabilityContext : document.managedObjectContext } : nil;            [[NSNotificationCenter defaultCenter] postNotificationName:PhotoDatabaseAvailabilityNotification                                                                object:self                                                              userInfo:userInfo];        }    }];    ...}

让TopRegionsTVC接收这个通知

#import "PhotoDatabaseAvailability.h"

- (void)awakeFromNib{    [super awakeFromNib];    [[NSNotificationCenter defaultCenter] addObserverForName:PhotoDatabaseAvailabilityNotification                                                      object:nil                                                       queue:nil                                                  usingBlock:^(NSNotification *note) {                                                      self.managedObjectContext = note.userInfo[PhotoDatabaseAvailabilityContext];                                                  }];}
<span style="font-weight: bold; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span>
<span style="font-weight: bold; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">2.The popularity of a region is determined by how many different photographers have taken a photo in that region among the photos you’ve downloaded from Flickr. Only show the 50 most popular regions in your UI (it is okay if the table temporarily shows more than 50 as data is loaded into the database, but re-set it to 50 occasionally). </span>

3.The list of top regions must be sorted first by popularity (most popular first, of course) and secondarily by the name of the region. Display the number of different photographers who have taken a photo in that region as a subtitle in each row. 


获取到managedContext后,我们需要设置前面说的fetchedResultsController

@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;...#define NUMBER_OF_SHOWN_REGIONS 50- (void)setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext{    _managedObjectContext = managedObjectContext;        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Region"];    request.predicate = [NSPredicate predicateWithFormat:@"name.length > 0"];    request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"photographerCount"                                                              ascending:NO                                 ],[NSSortDescriptor                                    sortDescriptorWithKey:@"name"                                    ascending:YES                                    selector:@selector(localizedCaseInsensitiveCompare:)]];    request.fetchLimit = NUMBER_OF_SHOWN_REGIONS;        self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request                                                                        managedObjectContext:managedObjectContext                                                                          sectionNameKeyPath:nil                                                                                   cacheName:nil];}

那么re-set it to 50 occasionally是神马意思?当我们从网络重新获取数据时,我们前面设置的50个就不起作用了(因为我们只有在notification中接收到了这个context,他并不会自动更新),所以这里我们使用一个通知来检测数据库的变化(当数据库保存时,发送和接收这个通知),然后重新performFetch

- (void)viewDidAppear:(BOOL)animated{    [super viewDidAppear:animated];    [[NSNotificationCenter defaultCenter] addObserver:self                                             selector:@selector(contextChanged:)                                                 name:NSManagedObjectContextDidSaveNotification                                               object:self.managedObjectContext];} - (void)viewWillDisappear:(BOOL)animated{    [[NSNotificationCenter defaultCenter] removeObserver:self                                                    name:NSManagedObjectContextDidSaveNotification                                                  object:self.managedObjectContext];    [super viewWillDisappear:animated];}  - (void)contextChanged:(NSNotification *)notification{    [self performFetch];}

好了,运行一下,如果没错的话,你会看到这样的界面


0 0
原创粉丝点击