Usage NSManagedObject model in code - ios

I have a User model class (generated by XCode with Swift):
#objc(User)
class User: NSManagedObject { }
And it's extension:
extension User {
#NSManaged var id: NSNumber?
#NSManaged var firstName: String?
#NSManaged var lastName: String?
#NSManaged var birthYear: NSNumber?
}
I can save/fetch data from CoreData.
But can I use this class for object management without CoreData things? Or i need to create other class/struct for this?
For example, create User object (without ObjectContext), set his attributes and send it as property in some func? Maybe i can create some struct in class User (like struct {var firstNameData, secondNameData,...}) and use it in code?

I updated class:
struct User {
var id: Int!
var firstName: String!
var lastName: String!
var birthYear: UInt?
}
#objc(UserManagedObject)
class UserManagedObject: NSManagedObject {
func toStruct() -> User {
var userData = User()
userData.id = Int(self.id)
userData.firstName = self.firstName
userData.lastName = self.lastName
if let by = self.birthYear {
userData.birthYear = UInt(by)
}
return userData
}
}
Now for object management i use struct User and UserManagedObject for CoreData in/out

Related

How to access an array of dictionaries in Parse API

I saved an array of dictionaries to Parse, which appears correctly in the User class. I can po user at a breakpoint and the array shows up properly as one of the properties on the User. However, I can't access this data at all, I get a runtime error of EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0). I'm trying to access the data using user.userFbFriendsDetail to save to a local variable. Here is the console result when I po User, I can't figure out how to use the userFBFriendsDetail array. Thanks a lot for your help!
<PFUser: 0x7fe1dd281010, objectId: onHQnYR5d2, localId: (null)> {
facebookID = xxxxxxx
fbEmail = xxxxxx
fbGender = male;
fbName = "John Doe";
friendsUsingTheApp = (
"<PFUser: 0x7fe1dbd30210, objectId: oqKnKZMN3d, localId: (null)>",
"<PFUser: 0x7fe1dbd30510, objectId: hUNZvZC4fD, localId: (null)>"
);
userFbFriendsDetail = (
{
email = "fake#fake.com";
facebookID = 1111111111;
profileImage = "<PFFile: 0x7fe1dfe28422>";
},
{
email = "fake#fake.com";
facebookID = 222222222222;
profileImage = "<PFFile: 0x7fe1dbd1ffd1>";
}
);
}
EDIT: Here is the definition of the PFUser class:
class User : PFUser {
override class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0;
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
#NSManaged var gender: String?
#NSManaged var fbName: String?
#NSManaged var age: NSNumber?
#NSManaged var facebookID: String?
#NSManaged var fbLocale: String?
#NSManaged var fbTimezone: NSNumber?
#NSManaged var fbGender: String?
#NSManaged var fbEmail: String?
#NSManaged var fbAge: NSNumber?
#NSManaged var profileImage: PFFile?
#NSManaged var twitterHandle: String?
#NSManaged var state: String?
#NSManaged var birthday: String?
#NSManaged var friendsUsingTheApp:Array<String>
#NSManaged var userFbFriendsDetailDict:Dictionary<String, AnyObject>
}
userFbFriendsDetailDict should be of type Array<Dictionary<String, AnyObject>>. (And you should access it under that name, not userFbFriendsDetail).

Parse+Swift, "-[Swift._NSContiguousString objectId]: unrecognized selector sent to instance" error

I'm using Parse and I had a PFObject I was using to represent a "Job". It worked fined, but it was tedious always using setObject:forKey: and objectForKey: rather than accessing properties.
So, I decided to make a "proper" PFObject subclass. Now, every call made to "objectId" gives the above unrecognized selector error -- even calls that have nothing to do with my subclass.
I created my subclass "by the book", as far as I can tell (below), and I do call Job.registerSubclass() before Parse.setApplicationId: in my AppDelegate. Anybody seen this problem?
import Foundation
import Parse
class Job: PFObject, PFSubclassing {
#NSManaged var categoryName: String
#NSManaged var categoryId: String
#NSManaged var state: String
#NSManaged var details: String?
#NSManaged var jobDescription: String
#NSManaged var location: String
#NSManaged var dates: [String]
#NSManaged var images: PFFile?
#NSManaged var questionSequence: [String]?
#NSManaged var consumerResponseIndices: [Int]?
#NSManaged var isPosted: Bool
#NSManaged var bids: [AnyObject]?
override class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0;
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String {
return "Job"
}
}
I got the same issue before.
You may have this error when trying to convert NSArray/NSDictionary to String type, so it turns to NSContiguousString type.
You can check:
dates
questionSequence
consumerResponseIndices
bids
to see if this happened.
In my case the problem was :
if let countryLocale = (notification.userInfo![Constants.CountryLocale]!.firstObject as? String { code }
and solved with
if let countryLocale = (notification.userInfo![Constants.CountryLocale] as! [AnyObject]).first as? String { code }

How to initialize Parse pointer in my subclass

I know how to set up strings and such, but how to set up a pointer to another class? Thanks!
import UIKit
import Parse
class Tag: PFObject {
override class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0;
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
#NSManaged var ID: String?
#NSManaged var stanceName: String?
#NSManaged var stanceValue: NSNumber?
// HOW DO I DO SOMETHING LIKE THIS?
#NSManaged var user: PointerToUserClass?
}
The user class is special, do it this way:
#NSManaged var user: PFUser?
For other Parse objects, use:
#NSManaged var object: PFObject?
Or, if you've subclassed the Parse object, then you can use your subclass:
#NSManaged var myTag: Tag?

Swift core data removing entries in one to many relationships

I'm using Xcode 6.4 and Swift in iOS 8.4 project
I have a model with one to many relationship
class Account: NSManagedObject {
#NSManaged var userId: Int
#NSManaged var accessToken: String?
#NSManaged var userName: String
#NSManaged var sex: String
#NSManaged var email: String
#NSManaged var avatarUrl: String?
#NSManaged var friends: NSSet
}
class User: NSManagedObject {
#NSManaged var id: Int
#NSManaged var userName: String
#NSManaged var sex: String
#NSManaged var email: String
#NSManaged var avatarUrl: String
}
When I'm trying to remove all friends it doesn't work:
extension Account {
func replaceFriends(friends:[User]) {
var friendsList = self.mutableSetValueForKey("friends")
friendsList.removeAllObjects()
friendsList.addObjectsFromArray(friends)
}
func getFriends() -> [User] {
return self.mutableSetValueForKey("friends").allObjects as! [User]
}
}
class AccountDao: BaseDao {
private class func findAccount() -> Account? {
if let result = moc.executeFetchRequest(NSFetchRequest(entityName: "Account"), error: nil) as? [Account] {
if (!result.isEmpty) {
return result[0]
}
}
return nil
}
class func getAccount() -> Account {
return findAccount() ??
NSEntityDescription.insertNewObjectForEntityForName("Account", inManagedObjectContext: moc) as! Account;
}
}
During saving I'm setting empty array:
class func saveObjectContext() -> Bool {
var error: NSError?
var account = AccountDao.getAccount()
account.replaceFriends([User]())
if !moc.save(&error) {
self.log.error("Error during saving context, \(error)")
return false
} else {
println("Count in log \(AccountDao.getAccount().getFriends().count)")
self.log.info("Info save context \(error)")
return true
}
}
In log it returns 0:
Count in log 0
But in ControllerView still I'm getting AccountDao.getAccount().getFriends().count == 1. Method replaceFriends works only first time when I fetch and save data. And it save changes for simple properties like userName but not for friends. Do you have any ideas?
I found that in relation one to many Account -> User without inverse relationship in User, after changing list in Account every user in list have to be marked that has changed (property updated == true). But it always was set to false.
I added additional property to User, and after every change of list I had to change this property like user.toUpdate = true. After this change everything is working fine.

Core Data with Swift two entities

I am trying to use Core Data to save some of my application data. I have following classes. Basically I want to store the properties of each job, and use it later on.
Following is the class I currently use in my application.
class Job {
var name:String?
var count = 1
var id:String
var startDate:NSDate?
var finishDate:NSDate?
var expected:NSDate?
var detail:Array<JobDetail> = []
var isFinished:Bool?
var sender:String?
var receiver:String?
init(name:String?, id:String) {
self.name = name
self.id = id
self.isFinished = false
self.startDate = NSDate()
}
func addDetail (message:String?, date:NSDate?, location:String?, status: DetailStatus) {
detail.append(JobDetail(message: message, date: date, location: location, status: status))
if status == DetailStatus.OK {
self.isFinished = true
self.finishDate = date
}
}
}
enum DetailStatus {
case OK
case Error
case Exception
case Unknown
}
class JobDetail {
var message:String?
var date:NSDate?
var location:String?
var status:DetailStatus
init(message:String?, date:NSDate?, location:String?, status: DetailStatus) {
self.message = message
self.date = date
self.location = location
self.status = status
}
}
NSManagedObject sub class I created with Xcode after I create the data model.
class Job: NSManagedObject {
#NSManaged var name: String
#NSManaged var count: NSNumber
#NSManaged var id: String
#NSManaged var startDate: NSDate
#NSManaged var finishDate: NSDate
#NSManaged var expected: NSDate
#NSManaged var isFinished: NSNumber
#NSManaged var sender: String
#NSManaged var receiver: String
#NSManaged var details: NSSet
}
class JobDetail: NSManagedObject {
#NSManaged var message: String
#NSManaged var date: NSDate
#NSManaged var location: String
#NSManaged var status: NSNumber
#NSManaged var parent: Job
}
Here are the screenshots of my data model.
Basically I want to CRUD Job in my application so that I can show them in my tableview. I have everything setup, but because I couldn’t setup Core Data I don’t have persistence. I will appreciate if you can help me to setup Core Data.
Refer this. May be it's useful to you...
http://www.raywenderlich.com/85578/first-core-data-app-using-swift
It seems from the screenshots that your setup is correct. Link details with jobs like this.
detail1.parent = job
detail2.parent = job
context.save(nil)
Get all details for a job like this
job.details
This is unordered, but you can sort them using sortedArrayUsingDescriptors.
let sortedDetails = job.details.sortedArrayUsingDescriptors(
[NSSortDescriptor(key:"date" ascending: false)])

Resources