【问题标题】:Fetching CoreData in IOS在 IOS 中获取 CoreData
【发布时间】:2015-03-24 18:00:17
【问题描述】:

我是 CoreData 的新手,我正在学习一些教程。

这是我的数据模型:

我想构建类似于实时乐谱的东西。所以我添加了一些遵循这种格式的演示数据:

// -------------------------------------------------------------------------
// --   GW :    1                                           2
//              |                                           |
//          Premier League                               Primera
//         /            \                                   |
//  Chelsea vs M.City  Arsenal vs Liverpool      Real Mad vs Barcelona
// -------------------------------------------------------------------------

我可以验证它们是否已保存,正如您从下面的屏幕截图中看到的那样:

所以,现在我需要做的就是将这些数据提取到我的应用程序中。我已经添加了这些调试功能:

# pragma -
# pragma  mark - different fetch functions

- (void) fetchGameweeksAndLeagues {
    /*
     Set up the fetched results controller.
     */
    NSLog(@"Fetch Gameweeks and Leagues");
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entityGW = [NSEntityDescription entityForName:@"GameWeek" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entityGW];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    NSError *fetchError = nil;
    NSArray *result = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];

    if (!fetchError) {
        for (NSManagedObject *managedObject in result) {
            NSLog(@"GwId:%@, League: %@", [managedObject valueForKey:@"gwId"], [[managedObject valueForKey:@"leagues"] valueForKey:@"leagueName"]/*,[[managedObject valueForKey:@"matches"] valueForKey:@"homeTeam"],[[managedObject valueForKey:@"matches"] valueForKey:@"awayTeam"]*/);
        }

    } else {
        NSLog(@"Error fetching data.");
        NSLog(@"%@, %@", fetchError, fetchError.localizedDescription);
    }
}

-(void) fetchMatchesForLeagueWithId/*:(NSNumber*)leagueId*/
{
    NSLog(@"Fetch Matches for specific League");
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entityLeague = [NSEntityDescription entityForName:@"League" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entityLeague];


    NSError *fetchError = nil;
    NSArray *result = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError];

    if (!fetchError) {
        for (NSManagedObject *managedObject in result) {
            NSLog(@"League: %@, Teams : %@ vs %@", [managedObject valueForKey:@"leagueName"],[[managedObject valueForKey:@"matches"] valueForKey:@"homeTeam"],[[managedObject valueForKey:@"matches"] valueForKey:@"awayTeam"]);
        }
    } else {
        NSLog(@"Error fetching data.");
        NSLog(@"%@, %@", fetchError, fetchError.localizedDescription);
    }
}

所以,我的输出是:

2015-03-24 17:38:42.236 SofaRef[73743:2215371] GwId:1, League: {(
    "Premier League"
)}
2015-03-24 17:38:42.236 SofaRef[73743:2215371] GwId:2, League: {(
    Primera
)}
2015-03-24 17:38:42.236 SofaRef[73743:2215371] Fetch Matches for specific League
2015-03-24 17:38:42.237 SofaRef[73743:2215371] League: Primera, Teams : {(
    "Real Madrid"
)} vs {(
    Barcelona
)}
2015-03-24 17:38:42.237 SofaRef[73743:2215371] League: Premier League, Teams : {(
    Chelsea,
    Arsenal
)} vs {(
    Liverpool,
    "Man.City"
)}

那么,我怎样才能以正确的顺序打印它们?

我想以与它们在数据库中相同的方式并以相同的顺序实际打印它们。这意味着打印切尔西 vs 曼城和阿森纳 vs 利物浦,而不是“按”列“分组” - 我想将它们作为“行”获取。

【问题讨论】:

    标签: ios objective-c core-data


    【解决方案1】:

    因为 League 与 Match 的关系是一对多的,所以 Leaguematches 属性返回一个 NSSet,即 [managedObject valueForKey:@"matches"] 是一个 NSSet。在您的 NSLog 语句中,您使用:

    [[managedObject valueForKey:@"matches"] valueForKey:@"homeTeam"]
    

    这会获取上述 NSSet 的每个元素,获取 homeTeam 属性值,并将结果作为新的 NSSet 返回。当你记录这个 NSSet 时,它会列出所有的值:

    {(
        Chelsea,
        Arsenal
    )}
    

    但是由于 NSSet 是无序的,结果可能是任何顺序的。事实上,正如您的结果所示,价值

    [[managedObject valueForKey:@"matches"] valueForKey:@"awayTeam"]
    

    是相反的顺序:

    {(
        Liverpool,
        "Man.City"
    )}
    

    您需要做的是分别记录每个match,显示每个homeTeamawayTeam。您可以通过嵌套另一个 for 循环来做到这一点:

        for (NSManagedObject *managedObject in result) {
            NSLog(@"League: %@", [managedObject valueForKey:@"leagueName"]);
            for (NSManagedObject *match in [managedObject valueForKey:@"matches"]) {
                NSLog(@"Teams : %@ vs %@", [match valueForKey:@"homeTeam"],[match valueForKey:@"awayTeam"]);
            }
        }
    

    这将确保您的输出出现在“行”而不是“列”中。但它仍然以随机序列呈现匹配,这可能与 SQL 数据库中的序列匹配也可能不匹配。通常,您不应假定数据库中的条目是按任何特定顺序排列的。如果顺序很重要,则应在从数据库中获取值时指定它(或在获取它们后对其进行排序)。为此,请使用NSSortDescriptor。假设您的偏好是匹配按字母顺序使用homeTeam 排序;使用以下 sortDescriptor:

    NSSortDescriptor *homeTeamSort = [NSSortDescriptor sortDescriptorWithKey:@"homeTeam" ascending:YES];
    

    你要排序的集合是matches关系,所以修改上面的代码如下:

        for (NSManagedObject *managedObject in result) {
            NSLog(@"League: %@", [managedObject valueForKey:@"leagueName"]);
            NSSortDescriptor *homeTeamSort = [NSSortDescriptor sortDescriptorWithKey:@"homeTeam" ascending:YES];
            NSArray *sortedMatches = [[managedObject valueForKey:@"matches"] sortedArrayUsingDescriptors:@[homeTeamSort]];
            for (NSManagedObject *match in sortedMatches) {
                NSLog(@"Teams : %@ vs %@", [match valueForKey:@"homeTeam"],[match valueForKey:@"awayTeam"]);
            }
        }
    

    【讨论】:

      【解决方案2】:

      //核心数据演示

      import UIKit
      import CoreData
      
      class ViewController: UIViewController
      
      {
      @IBOutlet var txt_add: UITextField!
      @IBOutlet var txt_name: UITextField!
      let contex = ((UIApplication.shared.delegate) as! AppDelegate).persistentContainer.viewContext;
      override func viewDidLoad()
      {
          super.viewDidLoad()
          // Do any additional setup after loading the view, typically from a nib.
      }
      @IBAction func btn_insert(_ sender: UIButton)
      {
          let entity = NSEntityDescription.insertNewObject(forEntityName: "Employee", into: contex);
          entity.setValue(txt_name.text, forKey: "empname");
          entity.setValue(txt_add.text, forKey: "empadd");
          do
          {
              try contex.save();
          }
          catch
          {
      
          }
      }
      @IBAction func btn_select(_ sender: UIButton)
      {
          let entitydic = NSEntityDescription.entity(forEntityName: "Employee", in: contex);
          let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Employee")
          request.entity = entitydic;
          let pred = NSPredicate(format: "(empname = @%)", txt_name.text!);
          request.predicate = pred;
          do
          {
              let arr = try contex.fetch(request);
              if arr.count > 0
              {
                  let obj = arr[0] as! NSManagedObject;
                  txt_name.text = obj.value(forKey: "empname") as? String;
                  txt_add.text = obj.value(forKey: "empadd") as? String;
              }
          }
          catch
          {
      
          }
      }
      @IBAction func btn_update(_ sender: UIButton)
      {
          let entitydic = NSEntityDescription.entity(forEntityName: "Employee", in: contex);
          let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Employee")
          request.entity = entitydic;
          let pred = NSPredicate(format: "(empname = %@)", txt_name.text!);
          request.predicate = pred;
      
          do
          {
              let arr = try contex.fetch(request);
              if arr.count > 0
              {
                  let obj = arr[0] as! NSManagedObject;
                  obj.setValue(txt_name.text, forKey: "empname");
                  obj.setValue(txt_add.text, forKey: "empadd");
      
                  do
                  {
                      try  contex.save();
                  }
                  catch
                  {
      
                  }
              }
          }
          catch
          {
      
          }
      
      }
      
      @IBAction func btn_delete(_ sender: UIButton)
      {
          let entitydic = NSEntityDescription.entity(forEntityName: "Employee", in: contex);
          let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Employee");
          request.entity = entitydic;
          let pred = NSPredicate(format:"(empname = %@)", txt_name.text!);
          request.predicate = pred;
          do
          {
              let arr = try contex.fetch(request);
              if arr.count > 0
              {
                  let obj = arr[0] as! NSManagedObject;
                  contex.delete(obj)
      
                  do
                  {
                      try contex.save();
                  }
                  catch
                  {
      
                  }
              }
          }
          catch
          {
      
          }
      }
      override func didReceiveMemoryWarning()
      {
          super.didReceiveMemoryWarning()
          // Dispose of any resources that can be recreated.
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-04
        相关资源
        最近更新 更多