In native iOS, to authenticate a GameCenter player we call this just once:
GKLocalPlayer.LocalPlayer.AuthenticateHandler = delegate (UIViewController authenticationViewController, NSError error) // error is just to assist with debugging, eg error 5019 is no leaderboard setup in App Store Connect
{
// This is called multiple times:
// whenever app App is Foregrounded and Game Center player may have changed name or logged in or out
}
which all works fine.
However, in Unity I am calling this just once:
Social.localUser.Authenticate((bool success) =>
{
// This is only called once (eg with success=false if player is not logged in
});
But if I go to iPhone > Settings > Game Center and sign in then return to my game the callback is not called a second time.
So should Social.localUser.Authenticate be called every time the app is foregrounded?
Related
I am making a React Native app which talks to Spotify via this module: https://github.com/cjam/react-native-spotify-remote
The module has an event listener which allows us to listen to Spotify player state changes, for example:
import { remote as SpotifyRemote } from "react-native-spotify-remote";
// and in a React component:
SpotifyRemote.addListener("playerStateChanged", (state) => {
console.log(state);
});
The above works as long as our RN app is in focus. However, when the app is in the background (i.e. we are on a different app or the phone is locked), the event listner no longer gets triggered.
I am expecting the event listener to get triggered even when the app is running in the background but it isn't doing that.
Is there anyway to make this work even the app is not in focus? Thank you!
I want to execute some code in onBackgroundMessage when app is in background or killed.
I am getting push notifications as aspected but onBackgroundMessage function is never executed in iOS. It works perfectly in Android devices.
Here is my code:
Future<void> _backgroundHandler(RemoteMessage message) async{
await Firebase.initializeApp();
dynamic isCall = message.data['status'];
print(isCall);
if(isCall == 'call'){
//.....
}else{
NotificationHandler.flutterLocalNotificationPlugin.cancelAll();
}
FirebaseNotifications.showNotification(message.data);
}
Future<void> main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_backgroundHandler);
runApp(const MyApp());
}
I also add APNs and add capabilities Background Modes and Push Notifications. Tested on real device.
What should have to do to execute FirebaseMessaging.onBackgroundMessage function in iOS?
You need to set content-available to true in your notification payload from backend.
This value let OS know that some data is available with the notification and allow that callback to be executed even when your app is in terminated state.
Client
for ios:
foreground - onMessage;
background - onBackgroundMessage;
terminated - onBackgroundMessage.
BUT
if app was terminated, first notification will be handled with getInitialMessage, because first notification wakes up the app
Server
exapmle of config:
messaging.Message(
token=recipient['fcm_token'], data={**message_data, 'user_id': str(recipient['user_id'])},
notification=messaging.Notification(
title=message_data['title'], body=message_data['body'], image=message_data['image'],
),
fcm_options=messaging.FCMOptions(analytics_label=message_data.get('analytics_label', None)),
apns=messaging.APNSConfig(
payload=messaging.APNSPayload(
aps=messaging.Aps(
content_available=True,
),
),
headers={'apns-priority': '5'},
),
)
need content_available=True and maybe headers={'apns-priority': '5'}
I have an application and PUSHs work fine when the app is on background I tap on push notification and it redirects me - OK.
But here is the situation which i have to fix:
1 step: I open the app, working with it, it is active
2 step: notification comes but user is not seeing anything AND he gets redirected to another ViewController(according to push notification info) UNEXPECTEDLY.
I need the app NOT to redirect anywhere when it is active unless the push notification is actually tapped.
I found a solution!
in didReceiveRemoteNotification method add if statement:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
if application.applicationState == .inactive || application.applicationState == .background {
//here add you actions
}
}
I have create an application which is sending data to watch for showing.
When the watch is screen is active then it sending data perfectly, but when watch sleeps then an error occurred that device is not active.
My question is that when the watch is active any how it will get that data which send via using WKSession sendMessage method from my iPhone?
If the watch screen is off, the calling sendMessage on the iPhone won't work. You can only send data in real time when the watch screen is on. This is different than when you are using sendMessage from the watch to the iPhone (iPhone screen can be off). This is the block of code I use anytime I call sendMessage from my iPhone code:
// Send messages to any paired apple watch.
func tryWatchSendMessage(message: [String : AnyObject]) {
if self.session != nil && self.session.paired && self.session.watchAppInstalled {
self.session.sendMessage(message, replyHandler: nil) { (error) -> Void in
// If the message failed to send, queue it up for future transfer
self.session.transferUserInfo(message)
}
}
}
Then I setup the apple watch app to have the same handler if it gets the data via sendMessage or transferUserInfo.
I have a simple Worklight V6 app using Push on Android. When the app starts up, it does a form based login against the SampleAppRealm. Then it subscribes if necessary:
function checkSubscribed() {
var subscribed = WL.Client.Push.isSubscribed("myPush");
alert("Is subscribed: " + subscribed);
return subscribed;
}
WL.Client.Push.onReadyToSubscribe = function() {
WL.Client.Push.registerEventSourceCallback("myPush", "PushAdapter",
"MyEventSource", function(props, payload) {
alert("Received message: " + props.alert);
});
if (!checkSubscribed()) {
WL.Client.Push.subscribe("myPush", {
onSuccess : function() {
alert("subscription succeeded!");
},
onFailure : function() {
alert("subscription failed!");
}
});
}
};
This all works swell. The app starts up, it logs in, onReadyToSubscribe() fires, it registers the callback, checks the subscription (which is false), and subscribes (which succeeds)
I can see the client subscription in the Worklight console, and if I call the adapter, I get the notification in the app.
If I hit the home button to do something else on the phone, and then return to the app, it still knows that it is subscribed. If I push a message when the app is in the background, I see it in the Android notification area, and see it in the app when I return to it. All good.
The problem is when I am running the app, it is subscribed, and I hit the Android back button. The app closes, but the Admin console still shows a subscribed client, and in fact if I push a message with the app closed, it shows up in the Android notification area. (so far so good)
But when I start the app, it goes through the authentication steps, onReadyToSubscribe() fires, checkSubscribed() gets called and WLClient.Push.isSubscribed() returns false.
If I restart the phone with the app subscribed, when the app restarts, WLClient.Push.isSubscribed() returns false.
How do I get the correct subscription state when an app restarts?
Answering my own question.
It turns out that the problem was that My app was explicitly calling WL.Client.login("SampleAppRealm") when it started. The application descriptor environment setting of a security test on the environment was not configured.
When I add the security test to the application descriptor, isSubscribed() returns the correct answer after an app is restarted. The funny bit is that everything else having to do with Push worked fine with authentication simply triggered by WL.Client.login()
I can't find any documentation around this requirement for the setting in the application descriptor, so it is hard to make out whether this is user error. At the least, the docs could be punched up in this area.