【问题标题】:iOS: Core data schema for follow systemiOS:关注系统的核心数据架构
【发布时间】:2016-04-05 23:14:49
【问题描述】:

我在 mysql 和 php 中有一个跟踪系统,它只使用一个表,如下所示:

关注

id|userid|followerid

(还有一个users表:id|username|pass)

每当用户关注另一个用户时,都会在关注列中使用 followerid 并在 userid 列中使用被关注的人进行条目。

我现在正尝试使用 Web 服务从 iOS 应用程序访问它。

对于 VC,我希望能够列出用户,但通过链接 NSPredicate 在用户的关注者和用户关注的人之间切换。这对于使用 php/sql 来说是微不足道的,但在转换为 CoreData 时需要花费一些时间。

现在我在核心数据中有用户实体,具有以下属性:

id|用户名|密码

并复制 mysql 架构,我还有一个以下实体 fid|fuserid|flowerid

反过来,我为用户与关注者创建了一对多关系,并为用户与关注者创建了反向一对多关系,因为给定用户(例如应用程序的用户)可以有很多关注者,也可以关注很多人。

Web 服务当前设置为向用户和每个用户提供一组关注者 ID,如下所示 编号:1 名称:鲍勃 追随者:2,3,4

此时我被难住了。我可以填充用户实体。我还可以用所有关注用户的人和用户关注的人填充关注者实体。

但是,我不知道要向 Core data 传达哪些关注者与哪个用户相关,而且我也不知道如何编写谓词,例如,仅拉取应用程序用户的关注者。

希望有任何建议。

现在我的 NSManagedObjects 如下所示:

   //User.h
    #import "Following.h"
    @class Following;

    @interface User : NSManagedObject
    //in user entity
    @property (nonatomic, retain) NSNumber * uid;
    @property (nonatomic, retain) NSString * uname;
    @property (nonatomic, retain) NSString *upass;

    //this is relationship
    @property (nonatomic, retain) Following *following;

    @end

//and Following.h   
     #import "User.h"
    @class User;

    @interface Following : NSManagedObject

    @property (nonatomic, retain) NSNumber * fid;
    @property (nonatomic, retain) NSNumber * fuserid;
    @property (nonatomic, retain) NSNumber * followerid;
    //this is relationship
    @property (nonatomic) User *user;

    @end

从网络服务导入和保存用户后,我尝试在关注实体中保存一些关于关注者的信息,但不确定我在这里做什么......

 NSSet*followerids = importUser.followerids;
                    NSInteger *folnum =[followerids count];
                    if (folnum>0) {
                    for (id item in followerids) {
                        Following *newFollowing = [NSEntityDescription insertNewObjectForEntityForName:@"Following" inManagedObjectContext:self.managedObjectContext];
                        newFollowing.fuserid = useridnum;
                         NSNumber *itemnum = [NSNumber numberWithInt:[item intValue]];
                        newFollowing.followerid = itemnum;
                        newFollowing.user = record;  //where record is a user just created     
                    }

【问题讨论】:

  • 我有点不清楚您要存储哪些用户和关系。您是否尝试将后端系统中存在的所有用户和关系存储在 Core Data 中?还是只有应用用户的关系?
  • 相当多的用户说大约有 20 个推荐用户,以便应用用户有机会关注他们。但就关注关系而言,只有应用用户当前关注的用户或当前关注应用用户的用户。

标签: ios core-data relationship


【解决方案1】:

您实际上拥有多对多关系(每个User 可以跟随许多其他Users,并且可以跟随许多Users)。您可以通过 two 对多关系 followedByUsersusersBeingFollowed 直接在 CoreData 中对此进行建模,而无需创建额外的实体,其中一个与另一个相反。生成的模型如下所示:

您的 User 类定义将如下所示:

@interface User : NSManagedObject
//in user entity
@property (nonatomic, retain) NSNumber *uid;
@property (nonatomic, retain) NSString *uname;
@property (nonatomic, retain) NSString *upass;

//this is relationship
@property (nonatomic, retain) NSSet *followedByUsers;
@property (nonatomic, retain) NSSet *usersBeingFollowed;

@end

如果您的网络服务提供useridname 和一组followerids,我将首先创建所有Users,而不设置任何关系,然后循环并通过获取来建立关系User对应followerids的记录:

NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"uid == %@",importUser.userid];
NSFetchRequest *fetchUser = [NSFetchRequest fetchRequestWithEntityName:@"User"];
fetchUser.predicate = userPredicate;
NSArray *results = [context executeFetchRequest:fetchUser error:nil];
User *record = results[0];
NSSet *followerids = importUser.followerids;
NSInteger folnum =[followerids count];
if (folnum>0) {
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"uid IN %@",followerids];
    NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"User"];
    fetch.predicate = predicate;
    NSArray *resultsArray = [context executeFetchRequest:fetch error:nil];
    if ([results count] > 0) {
        NSSet *followers = [NSSet setWithArray:resultsArray];
        record.followedByUsers = followers;
    }
}

(为简单起见,我省略了通常的错误检查。)建立关系后,您可以确定哪些用户关注给定用户:

givenUser.followedByUsers

或者,如果您想使用谓词(例如,对于 fetchedResultsController),请使用:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"usersBeingFollowed CONTAINS %@",givenUser];

相反,要获取givenUser 关注的用户,请使用

givenUser.usersBeingFollowed

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"followedByUsers CONTAINS %@",givenUser];

【讨论】:

  • 我认为前四个语句是为了获得正确的记录。现在我在创建和保存记录后立即执行此操作,如下所示: NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:self.managedObjectContext]; // 初始化记录 NSManagedObject *record = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];
  • 但是,即使我在 User.h 中添加了 followByUsers 属性,它仍然给我错误“在 NSManagedObject 类型的对象上找不到属性 followByUsers
  • @zztop 改成User *record = [[User alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];,所以它知道recordUser的子类NSManagedObject
  • 好的。我现在正在设置记录。当我将其注销时 record.followedByUsers 它显示:Relationship 'followedByUsers' on managed object (0x1558e6e0) (entity: User; id: 0x1564c530 ; 数据: { followByUsers = ( "..." ); following = ( ); uid = 5; uname = test; usersBeingFollowed = ( ); }) 与对象 {( ; 数据: { followByUsers = ( ); following = ( ); uid = 4; usersBeingFollowed = ( "..>" ); }) )}
  • 所以不确定我是否可以使用它。
【解决方案2】:

那么这里的关系有问题。根据您的解释,这里应该是多对多关系。

所以你的 User 类应该有一个类似的属性

//this is relationship
    @property (nonatomic, retain) NSSet *following;

你的关注类应该有一个类似的属性

@property (nonatomic) NSSet *users;

然后您可以开始将您从 web 服务接收到的追随者 ID 分配给它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多