核心数据关系:如何将新对象插入实体并创建与另一实体中现有对象的关系

Dea*_*ley 11 iphone xcode core-data objective-c ios

我正在构建一个小iPhone应用程序,允许用户保持他们可能正在与朋友一起玩的游戏的得分.我现在需要在Core Data中使用关系,但似乎无法让它工作.

我希望能够在创建与不同实体中的现有数据的关系的同时将新数据添加到一个实体中.我怎样才能做到这一点?

请注意我是Core Data的新手,今天花了很多时间试图解决这个问题,但运气不佳.任何帮助将非常感谢.


我有3个实体:得分,游戏玩家.

分数属性:date,player1Score,player2Scorestatus.

游戏属性:title.

玩家属性:name.

我有很多很多关系(分数 << --- >> 游戏)和(分数 << --- >> 玩家)


我已经有了一个游戏和玩家的列表.用户选择正在播放的游戏和谁,并且利用该信息,在得分实体中创建一组对象,其具有与所选择的游戏和玩家的关系.

这是我的来源:

//  Scores.h

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class Games, Players;

@interface Scores : NSManagedObject

@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) NSNumber * player1Score;
@property (nonatomic, retain) NSNumber * player2Score;
@property (nonatomic, retain) NSNumber * status;
@property (nonatomic, retain) NSSet *game;
@property (nonatomic, retain) NSSet *player;
@end

@interface Scores (CoreDataGeneratedAccessors)

- (void)addGameObject:(Games *)value;
- (void)removeGameObject:(Games *)value;
- (void)addGame:(NSSet *)values;
- (void)removeGame:(NSSet *)values;

- (void)addPlayerObject:(Players *)value;
- (void)removePlayerObject:(Players *)value;
- (void)addPlayer:(NSSet *)values;
- (void)removePlayer:(NSSet *)values;

@end
Run Code Online (Sandbox Code Playgroud)
// SC_ScoreViewController.h

#import <UIKit/UIKit.h>

@interface SC_ScoreViewController : UIViewController

@property (strong) NSIndexPath *game;
@property (strong) NSIndexPath *playerOne;
@property (strong) NSIndexPath *playerTwo;

@property (weak, nonatomic) IBOutlet UILabel *playerOneName;
@property (weak, nonatomic) IBOutlet UILabel *playerTwoName;

@end
Run Code Online (Sandbox Code Playgroud)
//  SC_ScoreViewController.m

#import "SC_ScoreViewController.h"
#import "Scores.h"
#import "Players.h"
#import "Games.h"

@interface SC_ScoreViewController ()

@end

@implementation SC_ScoreViewController

@synthesize game;
@synthesize playerOne;
@synthesize playerTwo;

// managedObjectContext (context)
- (NSManagedObjectContext *)managedObjectContext {
    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate respondsToSelector:@selector(managedObjectContext)]) {
        context = [delegate managedObjectContext];
    }
    return context;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Setup Nav Title
    self.navigationItem.title = [self.game valueForKey:@"title"];

    // Setup Player's Names
    [self.playerOneName setText:[self.playerOne valueForKey:@"name"]];
    [self.playerTwoName setText:[self.playerTwo valueForKey:@"name"]];


    Scores * newEntry = [NSEntityDescription insertNewObjectForEntityForName:@"Scores"        inManagedObjectContext:self.managedObjectContext];
    newEntry.player1Score = 0;
    newEntry.player2Score = 0;
    newEntry.status = nil;
    newEntry.player = self.playerOne; // Incompatible pointer types assigning to NSSet from NSIndexPath

    NSError *error;
    if (![self.managedObjectContext save:&error]) {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
    }

    - (void)didReceiveMemoryWarning
    {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }

    @end
Run Code Online (Sandbox Code Playgroud)

我希望我已经清楚并提供了足够的信息.这是我的第一个问题,所以我希望一切顺利.任何帮助都会很棒,谢谢.

Are*_*lko 8

您必须插入Players'对象self.managedObjectContext与插入新Score对象完全相同.它可能是这样的:

Scores *score = [NSEntityDescription insertNewObjectForEntityForName:@"Scores" inManagedObjectContext:self.managedObjectContext];
Player *player = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:self.managedObjectContext];
[score addPlayerObject:player];
Run Code Online (Sandbox Code Playgroud)

你还必须改变你的关系"得分<< --- >>玩家",因为现在你不知道哪个玩家是哪个.这里的其他选择是使用两个多对一关系(分别用于player1和player2).

还有一件事:以单数形式命名实体是最佳实践,因此Score,而不是Scores等等.

您应该阅读创建托管对象关系.这一切都很好地描述在那里.

更新:我认为游戏和分数之间不应存在多对多的关系(据我所知,分数可以重命名为匹配).它可能应该是一对多的关系.