CoreData batch insert Entities with Relationship - swift

Is there anyway to insert entities with relationship? I get error "Illegal attempt to establish a relationship 'content' between objects in different contexts"
addUsers(users: [userData])
func addUsers(users: [User]) {
let taskContext = container.viewContext
taskContext.perform {
let batchInsertRequest = self.newBatchInsertRequest(with: users)
if let fetchResult = try? taskContext.execute(batchInsertRequest),
let batchInsertResult = fetchResult as? NSBatchInsertResult,
let success = batchInsertResult.result as? Bool, success {
return
}
}
}
crash happens in below code
private func newBatchInsertRequest(with users: [Users]) -> NSBatchInsertRequest {
var index = 0
let total = message.count
let batchInsertRequest = NSBatchInsertRequest(entity: WaUser.entity(), managedObjectHandler: { managedObject in
guard index < total else { return true }
let user = users[index]
if let waUser = managedObject as? WaUser {
waUser.name = user.name
let waUserInfo = waUserInfo(context: self.container.viewContext)
waUserInfo.pass = "12345"
waUserInfo.key = "asdfgh"
waUser.info = waUserInfo **//crash occurs here**
}
index += 1
return false
})
return batchInsertRequest
}

Related

pull details from local database

I want to pull details from local database but when I do the necessary operations, it returns null as a result. I can't understand where I went wrong.
var chosenCar=""
var chosenCarId : UUID?
the arrays I created, I transfer data to these arrays, there is no problem with that, I did a test
if chosenCar != "" {
//core data
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "CarsInformation")
let idString = chosenCarId?.uuidString
fetchRequest.predicate = NSPredicate(format: "id = %#", idString!)
fetchRequest.returnsObjectsAsFaults = false
do {
let results = try context.fetch(fetchRequest)
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let name = result.value(forKey: "models") as? String {
modelTextField.text = name
}
if let year = result.value(forKey: "year") as? Int {
yearTextField.text = String(year)
}
if let price = result.value(forKey: "price") as? Int {
priceTextField.text = String(price)
}
if let imageData = result.value(forKey: "image") as? Data {
let image = UIImage(data: imageData)
imageView.image = image
}
}
}
} catch{
print("error")
}
} else {
modelTextField.text = ""
priceTextField.text = ""
yearTextField.text = ""
}
After doing these operations, I can't get the result I want.

Cant fetch SavedPost

My app has an option to save posts for users to watch later. The code is:
func savedPost(for cell: FirstView) {
guard let indexPath = collectionView.indexPath(for: cell) else { return }
var post = self.posts[indexPath.item]
guard let currentuserId = Auth.auth().currentUser?.uid else { return }
let targetUid = post.user.uid
guard let postId = post.id else { return }
let ref = Database.database().reference().child("save_post").child(currentuserId).child(postId)
if post.hasSaved {
ref.removeValue { (err, _) in
if let _ = err {
showErr(info: NSLocalizedString("failtoUnsave", comment: ""), subInfo: tryLater)
return
}
post.hasSaved = false
self.posts[indexPath.item] = post
self.collectionView.reloadItems(at: [indexPath])
}
} else {
let values = ["userId": targetUid]
ref.updateChildValues(values) { (err, ref) in
if let _ = err {
showErr(info: NSLocalizedString("failtoSave", comment: ""), subInfo: tryLater)
}
post.hasSaved = true
self.posts[indexPath.item] = post
self.collectionView.reloadItems(at: [indexPath])
}
}
}
With this code my firebase database in "save_post" has -> currentUseruId -> postid -> postUserId.
On ProfileController users can view saved Posts from "savedPost" Tab. The code is:
var savedPosts = [Post]()
fileprivate func fetchSaved() {
var userIds = [String]()
var postIds = [String]()
guard let uid = self.user?.uid else { return }
let getIDsRef = Database.database().reference().child("save_post").child(uid)
let query = getIDsRef.queryOrderedByKey()
query.observeSingleEvent(of: .value) { (snapshot) in
let dictionary = snapshot.value as? [String: Any]
dictionary?.forEach({ (key,value) in
guard let dic = value as? [String: String] else { return }
postIds.append(key)
userIds.append(dic["userId"] ?? "")
})
var i = 0
while i < userIds.count {
self.fetchPostsWithUserIDPostID(userID: userIds[i], postID: postIds[i])
i += 1
}
}
}
fileprivate func fetchPostsWithUserIDPostID(userID: String, postID: String) {
let getPostRef = Database.database().reference().child("video_list")
getPostRef.child(userID).child(postID).observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String: Any] else { return }
let ref = Database.database().reference().child("users").child(userID)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
guard let dict = snapshot.value as? [String: Any] else { return }
let user = User(uid: userID, dictionary: dict)
var post = Post(user: user, dictionary: dictionary)
post.id = postID
guard let currentUserUID = Auth.auth().currentUser?.uid else { return }
Database.database().reference().child("likes").child(postID).child(currentUserUID).observeSingleEvent(of: .value, with: { (snapshot) in
if let value = snapshot.value as? Int, value == 1 {
post.hasLiked = true
} else {
post.hasLiked = false
}
post.hasSaved = true
self.savedPosts.append(post)
self.savedPosts.sort(by: { (p1, p2) -> Bool in
return p1.creationDate.compare(p2.creationDate) == .orderedDescending
})
self.collectionView.reloadData()
})
})
})
}
However, when I click "savedPost" tab, there is no post shown. I don't know where my mistake is. I have all the necessary code under all override func collectionView(....). I believe the error should come from the code listed above. I am sincerely looking for help to resolve this issue. Thanks.
There could be a number of things going on here. It would be good to throw some print statements in there to make sure that 1) the data you're getting back from the database looks like what you expect, and 2) that you're properly parsing it into Post objects. Do you have your cells defined properly for your CollectionView? Also, I don't see where you are defining the data source for the CollectionView.

SWIFT4 Contextual type 'FPChat!.Type' cannot be used with dictionary literal

I need to initialize an object, and pass it through a prepareforsegue to another class.
Last line of the code below throws "Contextual type 'FPChat!.Type' cannot be used with dictionary literal"
if (segue.identifier == "chatmessages") {
let vc = segue.destination as! FPChatMessageViewController
//vc.currentChat = fPChat
}
}
fPchat = FPChat?
// Start the Chat
#IBAction func Chat(_ sender: UIButton) {
// Create a new entry in chats. This variable is passed with prepareforsegue
let chatRef = ref.child("chats").childByAutoId()
let chatId = chatRef.key
//fPchat = FPChat?
let fPchat = FPChat.currentChat(currentChatID: chatId)
Below chat class:
import Firebase
class FPChat {
var chatID = ""
var chatDate: Date!
var text = ""
var messages: [FPChatMessage]!
var author: FPUser!
var mine = true
// Calling FPChat.currentChat(id) I have back the FPChat object
static func currentChat(currentChatID: String) -> FPChat {
return FPChat(chatID: currentChatID)
}
private init(chatID: String) {
self.chatID = chatID
}
init(snapshot: DataSnapshot, andMessages messages: [FPChatMessage]) {
guard let value = snapshot.value as? [String: Any] else { return }
self.chatID = snapshot.key
if let text = value["text"] as? String {
self.text = text
}
guard let timestamp = value["timestamp"] as? Double else { return }
self.chatDate = Date(timeIntervalSince1970: (timestamp / 1_000.0))
guard let author = value["author"] as? [String: String] else { return }
self.author = FPUser(dictionary: author)
self.messages = messages
self.mine = self.author.userID == Auth.auth().currentUser?.uid
}
}
What I am doing wrong?

Core Data Condition

I need to add a Core Data condition How do I do it? . If the record is in this condition, the "sonuc" variable will be true
Core data model:
If "kullaniciadi" is "emre" and "otogiris" is "1" then the "sonuc" will
be true
func getContext () -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
if #available(iOS 10.0, *) {
return appDelegate.persistentContainer.viewContext
} else {
return DatabaseController.managedObjectContext
}
}
func otomatikGirisKontrol() -> Bool
{
var sonuc = false
let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Kullanicilar")
fetchRequest.returnsObjectsAsFaults = false
do{
let results = try getContext().fetch(fetchRequest)
if results.count > 0
{
sonuc = true
}
else
{
sonuc = false
}
}
catch
{
}
return (sonuc)
}
Use a NSPredicate to fetch only Kullaniciar objects fitting your condition:
let fetchRequest = ...
let kullaniciadi = "emre"
let otogiris = "1"
let predicate = NSPredicate(format: "kullaniciadi = %# AND otogiris = %#", kullaniciadi, otogiris)
request.predicate = predicate
//... execute fetch request

realmOC can't update data

addobject is success. but i want to update data. After realm.beginWriteTransaction() executes, breakpoint can't continue execute backup.quanId = 5, it's like just jump over.
class YQQuanBackup: RLMObject {
dynamic var groupId:Int = 0
dynamic var quanId:Int = 0
dynamic var content:String = ""
}
GCDBlock.async(.Default) {
let results:RLMResults = YQQuanBackup.objectsWhere("groupId == %d", self.groupInfo!.groupId)
let quanBackup = results.firstObject() as? YQQuanBackup
guard let backup = quanBackup else { return }
let realm = RLMRealm.defaultRealm()
realm.beginWriteTransaction()
backup.quanId = 5
backup.content = YQRichTextUtil.richTextToPublishText(self.textView.attributedText, uploadedImageUrls: self.uploadedImageUrls)
do {
try realm.commitWriteTransaction()
} catch {
print(error)
}
}