Clean UI elements watchOS 2 after lock - user-interface

When the app starts is Apple watchOS2 it calls:
awakeWithContext
Then, if you lock and unlock the app, the lifecycle calls:
willActivate
The problem that I have is that I cannot remove the UI elements (clean screen), without user see the "old" screen during 1 second.
From the Apple documentation:
didDeactivate:
-Do not use this method to modify your interface......Modifications can be made only during initialization of your interface controller and between calls to willActivate and this method.
but then in willActivate method:
.... Do not use this method to perform the initial setup of your interface.
I don't know what I have to do to "clean" the screen when the user locks the app.
Thanks for your time.

The answer from Apple:
Thank you for contacting Apple Developer Technical Support (DTS). Our engineers have reviewed your request and have concluded that there is no supported way to achieve the desired functionality given the currently shipping system configurations.

Related

Plugin.InAppBilling InAppBillingPurchase.PurchaseToken is sometimes null in production

I'm using James Montemagno's Plugin.InAppBilling library for Xamarin to do iOS and Android in-app subscriptions. It has worked mostly correctly so far, except that once in a while, on iOS only, InAppBillingPurchase.PurchaseToken comes back null from calls to PurchaseAsync and GetPurchasesAsync.
For example, in my Restore Purchases logic, I have code similar to this:
var purchases = await CrossInAppBilling.Current.GetPurchasesAsync(ItemType.Subscription);
// Sometimes we receive purchases with no PurchaseToken.
// Can't verify the purchase without a token.
var verifiable = purchases.Where(p => !string.IsNullOrWhiteSpace(p.PurchaseToken));
At this point, verifiable sometimes has a different count (0) than purchases (1).
So far, this has seemed to happen when the user purchased using either store credit or a gift card, and only on iOS.
Also, I'm not sure if this bears on the problem, but I am not using the overloads of PurchaseAsync and GetPurchasesAsync which take IInAppBillingVerifyPurchase, because I use server-side verification exclusively (no client-side verification). My workflow is to make the purchase, add the resulting InAppPurchase object to a queue for processing, and then send it to our server as a separate step, for validation and association with the user's account. However, if this is not a valid workflow or if it is known that sometimes PurchaseToken data will be available via IInAppBillingVerifyPurchase.VerifyPurchase but not attached to the InAppBillingPurchase objects returned from the methods above, I would certainly like to know about that. (For what it's worth, I've read the documentation and don't see anything that suggests this.)
Thanks in advance for any help.
Okay, I think I've learned enough to provide useful information for anyone else dealing with this issue.
First, I've figured out what Apple means by "iOS 6 style" and "iOS 7 style" receipts. These do not refer to the version of iOS that creates the receipts. (My up-to-date iOS 12 device still can and does generate "iOS 6 style" receipts.) Instead, these refer to two different receipt formats that were introduced in the respective iOS versions.
iOS 6 style receipts come from SKPaymentTransaction.transactionReceipt and contain information about one specific transaction. This field is now deprecated by Apple.
iOS 7 style receipts come from the app bundle, via the location named in NSBundle.mainBundle.appStoreReceiptUrl. These receipts contain a full manifest of all purchases ever made by the user. The receipts don't expire either -- you can always send them to Apple for validation (though, obviously, individual transactions contained within might show as expired in the response). These are the receipts you should prefer.
The reason this is important is that if you're using the Plugin.InAppBilling library, the InAppBillingPurchase object you get from calling something like PurchaseAsync contains the deprecated iOS 6 style receipt in its PurchaseToken field.
I'm still not sure why it is sometimes present and sometimes null, but seeing as the underlying source of the data is deprecated, it's probably safe to assume that this can and will happen. Therefore, it probably makes sense to cut over to the iOS 7 style receipts as soon as possible.
Note that when you call PurchaseAsync, if you specify an implementation of IInAppBillingVerifyPurchase, your IInAppBillingVerifyPurchase.VerifyPurchase method will receive the newer iOS7 receipt instead. However, the InAppBillingPurchase object returned by PurchaseAsync still gets an iOS 6 style receipt (if it gets anything at all).
Personally, I like the InAppBillingPurchase object itself. It has useful information packed into a convenient package. Since I want to keep the serialized InAppBillingPurchase objects in a queue so that I can retry validation if there are problems with our servers, connectivity, etc, what I'm doing is immediately replacing the PurchaseToken property with the iOS 7 style receipt that I manually retrieve from the bundle.
If you do this, be sure that your code handles the slightly different formats of the iOS 6 and iOS 7 receipts properly. (Our earlier attempts had some errors stemming from not properly understanding what these terms meant.)
I hope this is useful to someone out there. Good luck!

Branch.io: detect first install from Unity

Trying to detect the first install event from branch.io link (succesfully implement link creating and sharing). I am using Unity branch sdk. The feature i try to create:
user_1 creates and share link to user_2.
When user_2 opens the link and install app i need to reward both of them (with inner in-game coins)
So i succesfully implement the 1. but I cant understand how to detect is user_2 installs the app or simply open it. All data that comes from branch.io UniversalObject callback doesn't contain information that i need.
Which the correct way to detect the install from code?
Alex from Branch here.
The callback parameter you need is +is_first_session. This is one of the parameters returned when the Branch session is initiated each time your app opens (you can find all all these parameters here). If this returns true, then that device has just installed the app (instead of opening it).
However, note that when these parameters are returned, it's impossible to immediately determine if the user is new (what you want), the device is new (not what you want, since the reward could be given twice if the user has installed on multiple devices), or neither (the user deleted the app and reinstalled on the same device). You would probably want to hold off on actually awarding the referral points until after the user has logged in with some sort of unique ID.
Branch also has a built-in feature for tracking referral points that might be useful. That lets you configure all the rules using the dashboard UI instead of needing to do it programmatically inside your app.

Android MediaRouter

I try to build a Titanium module for Mediarouter (Chromecast). The standard solution for it is the use a MediaRouteSelector that opens a dialog with elements of android-support-mediarouter.jar. If I build a demo app by using the chromecast module then the aapt tries to resolve dependencies to appcompat-v7. But a module can only work with one res folder.
My question: is it possible the get a mediaroute without UI? I mean to ask the android and the system give me a collection of connected devices (name and id), I build an own dialog box and the result of users select calls a method to commect with this selected device. This solution would avoid the res conflict.
Here the repo: https://github.com/AppWerft/Ti.Chromecast/tree/master/android
Thanks
MediaRoute has nothing to do with the UI itself. You can initiate a discovery on the local network for the routes that satisfy your search criteria and then register to be notified when a matching route is found or dropped out, etc. If you want to show your own UI, you'd need to manage the list yourself, both in terms of bookkeeping, interactions and presentation. Look at our Android sender documentation or one of our Android sample apps (e.g. MediaRoute-Cast-Button sample) to get an idea.

How to specify no actions for android wear notifications?

I have a couple actions for my notifications, however I don't want any of them available on android wear. I know I can specify a list of custom actions for android wear, but how do I specify none? (I've tried addActions with an empty list, but no luck - then it just shows all the actions)
I don't think this is possible in standard way. If you specify at least 1 action in WearableExtender then normal actions will be replaced with wearable actions, but as you've said - you want to have 0 wearable actions.
For me you have 2 solutions:
Go with the API design post alternative versions of actions with your WearableExtender. If really any of phone actions cannot be used on watch maybe you can think of anything else that would be useful. It won't hurt user to be able to perform any action from watch. Of course if that makes sense in your case.
If you want to "hack" it a bit you can "clone" the notification and make them a part of the same group. If you would set one as a "group summary" that one will show up only on phone and other will be visible only on wearable. That way you have ability to setup completely independent set of actions.
Sample code:
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
// configure your builder without actions
builder.setGroup(GROUP_TAG);
builder.setGroupSummary(false);
notificationManager.notify(WEARABLE_NOTIFICATION_ID, builder.build());
// add some actions that will be visible only on phone
builder.addAction(...)
builder.addAction(...)
builder.setGroupSummary(true);
notificationManager.notify(PHONE_NOTIFICATION_ID, builder.build());

Application that simulates copy/paste doesn't work after being sandboxed. How to get it working?

I am building an application that simulates user input (command+c and command+v). Before sandboxing it, everything worked fine, but now I am getting these errors from the console:
Firstly, when I fire it up:
5/27/13 1:35:11.980 AM appleeventsd[54]: A sandboxed application with pid 5343, "CopyBoard" checked in with appleeventsd, but its code signature could not be validated ( either because it was corrupt, or could not be read by appleeventsd ) and so it cannot receive AppleEvents targeted by name, bundle id, or signature. Error=ERROR: #100013 { "NSDescription"="SecCodeCopyGuestWithAttributes() returned 100013, -." } (handleMessage()/appleEventsD.cp #1755) com.apple.coreservices.appleevents.peer.0x7fa9b0411260.xpcq
Then, when I try to simulate command+c, I get:
5/27/13 1:52:22.980 AM WindowServer[85]: post_filtered_event_tap_data: Sender is prohibited from synthesizing events
5/27/13 1:52:23.000 AM kernel[0]: Sandbox: sandboxd(6515) deny mach-lookup com.apple.coresymbolicationd
5/27/13 1:52:24.252 AM sandboxd[6515]: ([5343]) CopyBoard(5343) deny hid-control
I'm looking for a solution that would allow me to copy and paste globally in a sandboxed environment. Is it possible that the Accessibility API is a good answer? Has my problem got anything to do with how I'm simulating user input? I'm very confused, thank you very much for helping.
The sandbox is designed to prevent exactly what you seem to be trying - allowing an application to simulate a user is defined as a security issue. If you have a narrow requirement which can be done safely you can submit it to Apple thorough bug reporter as an needed improvement to the sandbox.
The Accessibility API is not supported in general for this reason - no playing with other apps! This did not go down so well with all the developers which used it...
You can use AppleEvents in limited constrained circumstances and with the appropriate entitlements.
You'll probably need to go to developer.apple.com and read all the documents/view videos/etc you can find to see if what you wish is going to be possible.
The only point of hope I can offer you is that the sandbox is a moving target, so you may find you can do more than the above suggests. Go read. Good luck.

Resources