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

这篇文章是针对斯坦福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 *)application
didFinishLaunchingWithOptions:(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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值