After struggling to create Realm object in App Group, I seem to have hit the next issue.
Objects that save into Realm with no issues when in Documents directory does not seem to save when in App Groups.
realm.transactionWithBlock { () -> Void in
let testModel = TestModel(test: "xyz")
self.realm.addObject(testModel)
}
Is this a known issue?
All mutations including adds must happen in a write transaction. Like this:
self.realm.transactionWithBlock() {
self.realm.addObject(testModel)
}
Related
What is the most sensible way to save an entry from a public to private database using CloudKit
There is a similar question answered: here, but I didn't quite understand the solution in those words. I don't necessarily need code answers (though always appreciated), but the linked question confused me here:
That recordType would then have a field of type CKReference in which you save your user ID
Does it mean public entry has an array of references to all the users who saved it?
Currently I'm just creating a brand-new entry in the users private database based on the public one they chose to save. When I fetch public items I first query the saved items and cross reference so I can e.g. set the 'star' button to filled or unfilled. It feels very verbose and wrong, I would like to know how people manage this.
Example:
An app with two tabs/views - 'public' and 'private'. The public view is a list of strings (from the public database) and a star icon showing whether the user saved it or not, and the private view shows entries that are saved.
Thanks
Yes, that's their solution. If you want to keep your own, just create a copy of the record in your private db. In my code I create models for each record type with;
let publicDB: CKDatabase
let privateDB: CKDatabase
var saveToDB : CKDatabase
then;
... other code retrieved record R from public DB
now;
saveToDB = privateDB
saveToDB.save(R, completionHandler:
{
(record, error) -> Void in
if (error != nil)
{
// ... error handling...
completion(error)
}
else
{
completion(nil)
}
})
I currently code a Discord bot in Java with Discord4j. Now, I want to get the mentioned user IDs (already did that) and convert them into Member object, but I don't know how to do it.
That's my code currently:
public static void run(MessageCreateEvent event) {
if(event.getMessage().getUserMentionIds().toString() == "[]") {
Utils.sendMessageToChannel("ERROR: No User got mentioned.", event);
}
Snowflake userMentions = Snowflake.of(event.getMessage().getUserMentionIds().toString());
Member member = new Member(userMentions);
}
Discord4J does not allow the use of constructors on its entities and most objects. This is because all of the entities are built up from data from the cache and/or a rest request to discord.
To get a Member from a user ID you would do the following:
GatewayDiscordClient#getMemberById(guildId, userId).block();
If you just want the user, as Member requires the person be in the guild:
GatwayDiscordClient#getUserById(userId).block();
You can also do this reactively by (flat)mapping the Mono(s).
I am finishing up an app utilizing a local Realm database with three models. When I delete an object from the main master model, the connected objects in the child models are supposed to all delete, but only one of the objects in each model deletes. See the attache diagram.
Not sure where to go next. Any help will be greatly appreciated!
Thanks!
Blessings,
—Mark
This is the normal behavior of realm js.
When you delete one element of the master model, the child element related is still present on the database.
The only solution is to get all child element and delete them first.
For example if you have a Master model named "Order" and a child model named "customer" :
/** if you use realm-js **/
const order = realm.objects('Order').filtered(`id = 1`)[0]
realm.write(() => {
realm.delete(order.customer)
realm.delete(order)
})
also you can find related related post with the same question
here or
here
Anyone else with this question, knowing the child databases must be deleted first, the solution became self-evident. Thanks again for pointing this out!.
//get the object at indexPath.row
let a = self.master![indexPath.row]
let id = a.Id //master's record ID
let n = realm.objects(Child1.self).filter("Id = %#", id)
let r = realm.objects(Child2.self).filter("Id = %#", id)
//Delete object at indexPath.row
try! realm.write {
realm.delete(n)
realm.delete(r)
//delete last
realm.delete(a)
}
Blessings,
—Mark
In my app I am using a NSPersistantContainer with two NSManagedObjectContexts (viewContext & background context). All my read operations are performed on view context, while all my write operations are performed on the background context (shown below).
Creating a new Animal class
class func new(_ eid: String) {
//Create Animal Entity
let container = CoreDataService.persistentContainer
container.performBackgroundTask { (context) in
let mo = Animal(context: context)
mo.eid = eid
mo.lastModified = Date()
mo.purchaseDate = Date()
mo.uuid = UUID()
do {
try context.save()
}
catch let error {
print(error)
}
}
}
The problem I am having is I need to return the newly created NSManagedObject (Animal) back to the manager class, where the Animal.new(eid) was called, to be used to show the object properties.
I have experimented with using a completion handler, but had issues returning the value, as was using a background NSManagedObject in the main thread.
Using possible new function
Animal.new(eid) { (animal) in
if let animal = animal {
}
What is the best approach for returning a newly created NSManagedObject, created in a background context?
What I do is to keep my CoreData managed objects within my CoreDataManager class, not exposing them out to the rest of my framework. So methods that are to create one or more managed objects would accept the data as an unmanaged object, and then create the managed object but not return it (as callers already have the unmanaged object). When fetching from the CoreDataManager, I'd create and populate a unmanaged object(s) and return that.
Now part of why I do this is because I'm using CoreData in a framework, such that I'd never want to hand a managed object to a client app of my framework. But it also solves other problems like the one you described.
(When I write apps, I use Realm, and those objects can go straight to app's UI classes because Realm is so much easier to, erm, manage. :)
Context
I have problems using the method realm.add(object, update: true) successively.
I'm making WEB requests to my API, and I'm testing the case where internet connection is disabled. When a request failed and I get the response, I add an UnsynchronizedRequest realm object to Realm.
Problem
I have to test the case where I have to make multiples call to my API, so I will add multiple UnsynchronizedRequest objects to Realm.
I only start the next web request when I received the previous request response, so the requests are well chaining, there is no concurrent requests.
When I'm making only one request and that it failed, the object is well added to Realm.
But when I'm making more than one request, only the first is added to the Realm, and the others are not added.
What is strange is that when I'm using breakpoints, all objects are well added to Realm. But when I disable breakpoints, only the first UnsynchronizedRequest object is added to the Realm, the other are ignored.
I think it is a problem with the write thread, the doc says that it blocks other thread if multiple writes are concurrent, but I don't know how to solve it.
What I execute when a web request failed :
class func createUnsynchronizedRequest(withParameters parameters : Parameters, andRoute route : String){
print("Adding unsynchronized request to local...")
let failedRequest = UnsynchronizedRequest()
failedRequest.parameters = parameters
failedRequest.route = route
failedRequest.date = Date()
RealmManager.sharedInstance.addOrUpdate(object: failedRequest)
}
RealmManager.swift
func addOrUpdate(object : Object){
try! realm.write {
realm.add(object, update: true)
}
}
UnsynchronizedRequest.swift
#objcMembers class UnsynchronizedRequest : Object {
// MARK: - Realm Properties
override static func primaryKey() -> String? {
return "id"
}
dynamic var id = ""
dynamic var route = ""
dynamic var date : Date! {
didSet {
self.id = "\(self.date)"
}
}
}
I already tried to check if realm was in transaction in the addOrUpdate method before starting realm.write, this not solve the problem.
I also tried to catch the error with realm.write, but no error is thrown.
Furthermore, if I execute for example 3 time a web request et that is failed, I'm sure that my code is executed because the print in createUnsynchronizedRequest is working.
I really think it is a problem with write threads because when I use breakpoint to slow the code execution, everything works well.
Example with 3 failing web requests and USING BREAKPOINTS :
As you can see, using breakpoints, the 3 objects are well added to realm :
Example with the same 3 failing web requests and WITHOUT BREAKPOINTS :
But now without breakpoints, only the first object is added to Realm :
Any idea ?
As I created my UnsynchronizedRequest objects with the Date() method, the created objects had the same primary keys.
The space time between object creation is not sufficient to make a Date() object different than the previous created.