Is there a way to detect which contact records have changed ?
I understand there are 2 options to detect change:
kABDatabaseChangedNotification and
kABDatabaseChangedExternallyNotification
ABAddressBookRegisterExternalChangeCallback
I would like to detect each contact that has been changed. How would I be able to do this ?
I suppose there is no way to detect the individual changes.
Couple of points to keep in mind:
You need to use `ABAddressBookRegisterExternalChangeCallback1 to
specify the callback function
When the callback function is called reload all the contacts from address book.
Use NSOperation and ensure isCancelled is handled.
Related
We're using Realm (Swift binding currently in version 3.12.0) from the earliest days in our project. In some early versions before 1.0 Realm provided change listeners for Results without actually giving changeSets.
We used this a lot in order to find out if a specific Results list changed.
Later the guys at Realm exchanged this API with changeSet providing methods. We had to switch and are now mistreating this API just in order to find out if anything in a specific List changed (inserts, deletions, modifications).
Together with RxSwift we wrote our own implementation of Results change listening which looks like this:
public var observable: Observable<Base> {
return Observable.create { observer in
let token = self.base.observe { changes in
if case .update = changes {
observer.onNext(self.base)
}
}
observer.onNext(self.base)
return Disposables.create(with: {
observer.onCompleted()
token.invalidate()
})
}
}
When we now want to have consecutive updates on a list we subscribe like so:
someRealm.objects(SomeObject.self).filter(<some filter>).rx.observable
.subscribe(<subscription code that gets called on every update>)
//dispose code missing
We wrote the extension on RealmCollection so that we can subscribe to List type as well.
The concept is equal to RxRealm's approach.
So now in our App we have a lot of filtered lists/results that we are subscribing to.
When data gets more and more we notice significant performance losses when it comes to seeing a change visually after writing something into the DB.
For example:
Let's say we have a Car Realm Object class with some properties and some 1-to-n and some 1-to-1 relationships. One of the properties is a Bool, namely isDriving.
Now we have a lot of cars stored in the DB and bunch of change listeners with different filters listing to changes of the cars collection (collection observers listening for changeSets in order to find out if the list was changed).
If I take one car of some list and set the property of isDriving from false to true (important: we do writes in the background) ideally the change listener fires fast and I have the nearly immediate correct response to my write on the main thread.
Added with edit on 2019-06-19:
Let's make the scenario still a little more real:
Let's change something down the hierarchy, let's say the tires manufacturer's name. Let's say a Car has a List<Tire>, a Tire has a Manufacturer and a Manufacturer has aname.
Now we're still listing toResultscollection changes with some more or less complex filters applied.
Then we're changing the name of aManufacturer` which is connected to one of the tires which are connected to one of the cars which is in that filtered list.
Can this still be fast?
Obviously when the length of results/lists where change listeners are attached to gets longer Realm's internal change listener takes longer to calculate the differences and fires later.
So after a write we see the changes - in worst case - much later.
In our case this is not acceptable. So we are thinking through different scenarios.
One scenario would be to not use .observe on lists/results anymore and switch to Realm.observe which fires every time anything did change in the realm, which is not ideal, but it is fast because the change calculation process is skipped.
My question is: What can I do to solve this whole dilemma and make our app fast again?
The crucial thing is the threading stuff. We're always writing in the background due to our design. So the writes itself should be very fast, but then that stuff needs to synchronize to the other threads where Realms are open.
In my understanding that happens after the change detection for all Results has run through, is that right?
So when I read on another thread, the data is only fresh after the thread sync, which happens after all notifications were sent out. But I am not sure currently if the sync happens before, that would be more awesome, did not test it by now.
Currently I'm using Eventstore (by Greg Young) for my company project. In my read model, I store the processed event ids, not the event name. How can I find the event in Eventstore using its Id?
I don't think this is possible currently. I think you have two choices:
in your read model store the stream and index, or the commit/prepare position of the event and then read the event from either the $all stream using the commit/prepare position or from the stream it was written to using the stream and index. This is probably the simplest.
Or create a projection in event store which indexes the events by their id and reprojects into a stream called, say, eventid-{event.id} then you can read directly from this stream.
The second is backwards compatible with your current read model, but I'm not sure is the right thing to do, as projections cause write amplification, and you probably need to make sure you exclude system events from being projected.
You can query the event using the following URL path. This will return the event and the last 20 events before it
{youreventstoredomain}:2113/web/index.html#/streams/$ce-{streamname}/{eventnumber}/backward/20
I am new to Parse cloudcode and spinning my wheels to understand JS and write cloudCode to remove user from PFRelation. Can anyone please assist me with parse cloudcode snippet to remove user from PFRelation. I am trying to implement unfriend functionality in the iOS app and I can remove the friend from current users PFRelation and would like to remove current user from the friend PFRelation. I am completely blanked out and don't know how to do that.
I appreciate the help.
Thanks!
The javascript info (that's what you need to do this function on the server) is here: https://parse.com/docs/js_guide#objects-pointers
Specifically, the code on that page that you need is:
var relation = request.user.relation("friends");
relation.remove(other);
request.user.save();
Then you need to get a handle to the other user object and do the same thing there. Are you storing Parse.User objects, or IDs? If it's User objects, the whole code could be this:
var relation = request.user.relation("friends");
var other = relation[0]; // I'm not sure about array indexing though.
var otherRelation = other.relation("friends");
otherRelation.remove(user);
relation.remove(other);
other.save();
request.user.save();
Note that this code isn't really kosher from the perspective of "when the function returns, the logic is done". It's not, since the save is asynchronous. It's faster this way. You could make it both fast and kosher by running both together and waiting for both to finish, but it's been a long time since I've written JavaScript so I can't provide the exact code for that.
Edit: Don't forget to use Parse.Cloud.useMasterKey() to get the right permissions before you try modifying another user.
In Mixpanel you can track each action, like:
[mixpanel track:#"Watched Movie" properties:#{#"Movie ID”:#“1234", #"Movie Name”:#”Rocky 3"}];
And you can set user properties, like:
[mixpanel.people set:#{#"Eye Color":#"Blue"}];
When I want to send an email to a subset of users, I can narrow things down by asking for user properties - Eye Color:Green for instance.
But how do I get a subset of users who have performed a certain action - for instance "Watched Movie" with "Movie Name" "Rocky 3"?
As you have probably noticed, notifications can only be sent based on People Profile Properties. To segment people by events/send notifications based on events, you need to pass event data over to People by adding an extra line of code that sets the event as a people property. As of now, People and Engagement are two separate data sets. We're working on tying these data sets together more tightly, but for the moment they are not seamlessly integrated.
In your example, we would need to fire a people.set as the user watched a movie called Rocky 3
An example of this for iOS would be the following:
[mixpanel.people set:#{#"Rocky 3 Viewed":#"True"}];
Please feel free to write into support#mixpanel.com if you have any other questions!
I'm building a messaging application. I update the badge count in the database via a sqlite trigger whenever any operation like insert/delete/read message happens.
Currently, though the value update in the DB happens asynchronously, I have no way to get notified about when the value changes in my application and hence am polling periodically.
Is there some way to setup an observer on a database value/publish some notification when a given value changes?
I know that I can do this easily by first updating the badge count in an in-memory property and then persisting the changes to the DB; but I am not very inclined to do this, since there are too many entry points for this value to change, and I don't want to add a SET property everywhere.
One possible option would be to define a trigger that is only called when this specific value in the database is updated. The trigger should then make a call to a user defined function you create in your app. You use the sqlite3_create_function function to add your own function to SQLite. Your trigger would like something like:
CREATE TRIGGER some_trigger_name
AFTER UPDATE OF some_column ON some_table
FOR EACH ROW BEGIN
SELECT my_custom_fuction();
END;
If needed, you can pass 1 or more arguments to your function.
Though that this might not be an option for you, Core Data does this well.