How to receive UIAccessibilityNotifications in iPhone App - iphone

I'm interested in capturing UI changes in my application programmatically and thought that the UIAccessibility protocol may help. I've found how to post UIAccessibilityLayoutChangedNotification and UIAccessibilityScreenChangedNotification but I'm not sure how to register to receive these notifications.
I've tried using NSNotificationCenter, but the name param expects a string, while the two notifications above are of the type UIAccesibilityNotifications which is an int.
Any idea how to register for these notifications?
Thanks!

That's a great question! Unfortunately you cannot receive these "notifications" without affecting normal behavior. (i.e. "no you can't")
If you disassemble UIKit, you'll find UIAccessibilityPostNotification is implemented like this:
static void (*__UIAccessibilityBroadcastCallback)(UIAccessibilityNotifications notification, id argument);
void UIAccessibilityPostNotification(UIAccessibilityNotifications notification, id argument) {
__UIAccessibilityBroadcastCallback (notification, argument);
}
That means these accessibility "notifications" aren't any normal notifications. Rather, they are just parameters to an internal callback function. How the callback function is implemented depends on the accessibility bundle you're using.
You can replace the callback function with your own using the undocumented API _UIAccessibilitySetBroadcastCallback:
void _UIAccessibilitySetBroadcastCallback(void (*replacement)(UIAccessibilityNotifications notification, id argument)) {
__UIAccessibilityBroadcastCallback = replacement;
}
However, there isn't a corresponding "get" function (not even private), so once you set it, the original listeners cannot be notified again.

Related

GA4 Conversion tracking using Measurement Protocol

[Edited. Added code sample and more explanations]
Is anybody familiar with the GA4 Measurement Protocol?
We are sending events from our backend servers to the server-side GTM container using the GA4 Measurement Protocol. Everything works fine except for conversion tracking. The events marked as conversion are not counted as conversions if we send those via MP (except for the default "purchase" event, it works perfectly). The same event with the same parameters counts as a conversion if we send it from the browser (client-side GTM). As I couldn't find anything about this issue online, the only thing left was to debug parameter by parameter using the server-side GTM preview mode. Here I discovered, that if I send events from the browser, the requests for events I mark as conversions in GA have "&_c=1" in their query string.
That means, as far as I understand it, that in order to get conversion events via MP, the event request needs to have "_c" query string parameter. I tried adding "_c" as an event param, but that didn't work. Is there a designated JSON parameter to mark the event as a conversion?
------------MORE INFO--------------
Here is an example of an event "Experts". This event gets sent from both the client-side and the server. As you can see in the screenshot, this event is marked as a conversion.
As you can see on the second screenshot, the actual events (137) are much more than the conversions detected (48). The difference are exactly the ones sent from the server-side.
Here is the request body of the server call:
{
"client_id":"Z9TLWnyVC2UK4UssPIVk8J+2n5BZhgWLtWSlFYYSwlg=.1642076344",
"user_id":"119412",
"events": [{
"name": "Experts",
"params": {
"tenweb_action": "[Test action]",
"tenweb_info": "[Some more info]",
"debug_mode":1,
"page_location": "https://10web.io/[some-test-page]"
}
}]
}
#Jan, #DaImTo, and everyone else that might have this issue in the future.
I think I've found a solution. Although it's unofficial and might break at any moment, it's the best one I've found so far. Here is what I ended up doing. While debugging via GTM preview mode I noticed, that in Event Data tab of conversion events there is an object "x-ga-system_properties", that, among other system variables, contains c:"1" . So I tried adding
"x-ga-system_properties":{"c":"1"}
to the event parameters JSON that we send to the Measurement Protocol endpoint of our server-side GTM.
IT WORKED. The events sent that way were registered as conversions by GA4.
Would be great to hear your thoughts on this. Do you think it's a stable solution? Do you think there will be official documentation on this from Google?

Monitoring Keychain item changes in Swift

The Keychain Services API allows adding/updating/deleting items from the keychain. However, it doesn't seem to include any mechanism for watching a specific keychain item for changes.
My app is storing a value in the keychain, and I want to be notified if that value gets changed by the user or another process. Is such a thing possible, or will I just have to periodically poll the keychain item and check for changes myself?
Here is API of Security framework for your purpose
/**
#function SecKeychainAddCallback
#abstract Registers your keychain event callback function
#param callbackFunction A pointer to your keychain event callback function, described in SecKeychainCallback. You indicate the type of keychain events you want to receive by passing a bit mask of the desired events in the eventMask parameter.
#param eventMask A bit mask indicating the keychain events that your application wishes to be notified of. See SecKeychainEventMask for a description of this bit mask. The Keychain Manager tests this mask to determine the keychain events that you wish to receive, and passes these events in the keychainEvent parameter of your callback function. See SecKeychainEvent for a description of these events.
#param userContext A pointer to application-defined storage that will be passed to your callback function. Your application can use this to associate any particular call of SecKeychainAddCallback with any particular call of your keychain event callback function.
#result A result code. See "Security Error Codes" (SecBase.h).
*/
public func SecKeychainAddCallback(_ callbackFunction: SecKeychainCallback,
_ eventMask: SecKeychainEventMask,
_ userContext: UnsafeMutableRawPointer?) -> OSStatus

How to use standard events in the react native Facebook SDK

The Facebook SDK has the ability to record both custom events and standard events. The standard events are things like "Purchases" "Add to cart" "Completed Registration" etc...
Recording these standard events gives you access to specific bidding features on Facebook ads that you don't get without the events.
I have an app that has the React Native FBSDK
There are two methods for defining an event - one for purchases and one for everything else as seen here
There is zero documentation for standard events on react within the SDK on Github or on the event tracking docs on Facebook's developer platform.
Right now I'm trying to track the standard events by using their various names, as recorded across FB's documentation. I've tried the following:
AppEventsLogger.logEvent('FBSDKAppEventNameCompletedRegistration');
AppEventsLogger.logEvent('CompletedRegistration');
AppEventsLogger.logEvent('Completed Registration');
All of these just create custom events with those names, but aren't recognized as standard events.
Has anyone gotten standard events to work using the React Native wrapper for the FB SDK? If so how do you name the events to get FB to recognize them?
Update: As the comment below highlights, the more recent link is https://developers.facebook.com/docs/marketing-api/app-event-api/
It looks like you'll have to pass the strings that those standard events get evaluated to, i.e. instead of 'FBSDKAppEventNameCompletedRegistration', you'll have to use: 'fb_mobile_complete_registration'.
Here's the source:
Sorry if this is a bit late. Hope this helps.
I managed to find the actual event name by generating standard event code using tool on Facebook's documentation, run the code in AppDelegate.m, and get the exact key-values from Events Manager. With this roundabout way, I realized the actual name of Add to Cart event was fb_mobile_add_to_cart. From there I googled for the name and found the list documented in Marketing API (why not App Events?).
I don't know if it is the right place, but you can refer to https://developers.facebook.com/docs/marketing-api/app-event-api/ for actual standard event names and parameter names. At least it worked in my case. Here's my Add to Cart event code:
function logAddToCart(totalPrice, contentType, contentId, currency) {
const params = {
'fb_content_type': contentType,
'fb_content_id': contentId,
'fb_currency': currency
};
AppEventsLogger.logEvent('fb_mobile_add_to_cart', totalPrice, params);
}
I made a simple package with all events. Just import like
import FBEvents from "react-native-fbsdk-events";
// ...
AppEventsLogger(FBEvents.COMPLETE_REGISTRATITON, params);

Where does related logic go on model creation when working with REST api with Django, Backbone, and Tastypie?

We are trying to move some of our app to use backbone and tastypie. I have the REST api set up and it is working on some basic examples. However, there are a few issues where currently we post an ajax request to a custom url, and in that view do a few things like
make related objects
call a few related functions
However, now that I've switched some of this functionality to using backbone and the REST api, I'm not sure where all of that should go!
For example, I had a view to make a Message, and when I made a Message, I also made a Notification and called a function to add some points to the user. Something like
def ajax_send_message(request):
## ... set up some variables ...
## Make the new message
message = Message(user=user, content=message)
message.save()
## Make the notification
notification = Notification(message=message)
notification.save()
## Give the user points
user.add_points_for_message();
return json_response({"status": "ok"})
Now--am I just supposed to do this all in JavaScript? I have a Message Backbone model as well.
// Create message backbone object
var msg = new Message({content:content, user: user});
// Post to server
msg.save();
// Add to backbone collection
messages.add(msg);
I've looked at different parts of tastypie, and it seems you can create custom URL endpoints, and also do validation, but that doesnt seem like the right spot to call related methods. It seems that calling related methods goes against the REST part of it---but then where are they supposed to go?
If I want to add some logic to backbone only when an object is created, where does that go?
The first thing I would suggest is to switch your mindset to an event-based model, where your code reacts to events. In your example above, you save the model to the server then immediately dd it to the collection. How do you even know that the model was saved correctly? That procedural style of programming works better in a synchronous, server-side style of programming.
In the asynchronous world of client-side programming, you make a request and then set up callbacks which determine what will happen next, depending on the events your are listening for. In your case, you want to react a certain way when the message is saved successfully, correct? You can define a success callback for your save operation like so:
msg.save({
success: function(model, response, options) {
messages.add(model);
// code to add notification
// code to add points
}
});
Basically, you are saying "I would like to save this model, and then listen for a success event. When the event comes in, execute the following code." Notice also that I am adding the model returned from the API to the collection, since this is the exact object that was persisted to the server so it's more appropriate to add than the model you created.

ShareKit for iphone - SHKShareTypeText

I am using ShareKit for iphone to share some text in facebook. Can any one tell me which delegate is called after publishing the text successfully. I need this to inform the user that his action was successful.
The shareDelegate property in SHKSharer isn't the easiest to get to and change, but there are notifications sent from the delegate methods of SHKSharer, one for each of the methods: SHKSendDidStartNotification, SHKSendDidFinish, SHKSendDidCancel, SHKSendDidFailWithError. Observing these notifications turns out to be a simple way of listening for the outcome of sharing.
See shareDelegate property of SHKSharer . All the concrete sharers (e.g. SHKFacebook) extend this base class.
Having said that, I'm not sure where you set a class to be the delegate using ShareKit's public API (so I'm not claiming this to be a complete answer).