I'm using the SetSDK to show users the available bike share count at their nearby station whenever they leave their home. I'm following the example available in the pod documentation but am not getting the notification. Here is my code,
SetSDK.instance.onDeparture(.home) { notification in
// below is my code using the notification
let bikeStationCount = getAvailableBikes(stationsNear: notification.location)
showNotification(withCount: bikeStationCount.count, atStation: bikeStationCount.station)
}
But I'm not getting my app to show any notification, any idea what is wrong?
It looks like your code is correct. The only thing to keep in mind is that the SetSDK will learn the user's home over time, with most users it usually takes 1-2 days for it to have enough certainty to call a place Home.
Have you had a chance to let the SDK learn long enough that it is giving you notifications now?
Hey, cool use-case!
Related
I searching for a solution to tell a Linux-application that the iPhone left the house and come back again. (in Swift ;-) )
I testing some ways, but nothing works in the right way.
When i using WLAN-connection lost, so the Linux think that i'm away when my iPhone goes to standby, because iOS shutdown the WLAN in Background.
When i using background location the time between the location updates is too long.
Can i use the Homekit to do something like that? Or is there anyone who did something like this?
The SetSDK will allow you to setup an in-app notification for when a user arrives to or departs from home, https://cocoapods.org/pods/SetSDK. The SDK learns where home is and then starts to fire the notifications off. So for departing home, you would do,
SetSDK.instance.onDeparture(from: .home) {
/* do your Swift things here */
}
In that example, you rely on the SetSDK to learn where home is first. If you already know a location where you want to get departure alerts, the easiest right now is to do,
SetSDK.instance.onDeparture(from: .any) { departedPlace in
/* Compare the departed location with the one of interest */
if departedPlace.location.distance(from: knownLocation) < 50 {
/* do your things here */
}
}
So we have a notification screen where users can customize the push notifications they want to receive. In this view controller, we check if [application isRegisteredForRemoteNotifications], we allow users to use the screen, else we show them the prompt that deep links to settings for the app. Now, what's happing is that certain users are complaining that this prompt never disappears even when they turn on in settings. They have sent us the screenshot of the screen, as well as device settings for the app. We have not been able to reproduce this issue. The view controller is directly checking against the OS flag, so there is not much scope of error there. Also we have gone through the code and haven't found anything. I am assuming that because of network issues, deviceToken is not getting delivered to the app. Not really sure what else might be going here. Appreciate any help or suggestions on this matter.
I have an turn-based game using GameKit in iOS. Generally, my authentication with Game Center works. My game works and I can for periods of time send moves back and forth. However, relatively frequently but not constantly, when I try to perform an action (e.g., finding a new match) over Game Center it fails with the error:
Error Domain=GKErrorDomain Code=6 "The requested operation could not be completed because local player has not been authenticated." UserInfo={NSLocalizedDescription=The requested operation could not be completed because local player has not been authenticated.}
Yet, the GKLocalPlayer.localPlayer().authenticated = true, both immediately before getting the error and after. After getting this error, the authentication viewController does not get presented and GameKit methods that rely on authentication cease to function (they don't come back to life ). Then, if I send the app to the background and then bring it back to the foreground, the error does not return when I retry the action (without requiring new login and password entry).
According to this similar observation:
GKLocalPlayer authentication not working, but isAuthenticated returns YES (Game Center sandbox)
"1.Game Center fails to complete authentication if your device has incorrect dates. So, go ahead and check the current date.
You might have done this. I trust you - iOS Simulator >> Reset Content and Settings"
I am getting this problem on the device, not the simulator, ruling out #2. Could someone help me with #1? I may be naive here, but my iPhone and iPad have the right time and date. Is there something or somewhere else I should be checking and setting?
Then, if this is not the issue, what else could be the problem? I am running iOS9.
I've seen this too, and have an open bug with Apple. In my case, I'm testing with multiple physical devices, and only one of those devices ever encounters this. On that particular device, I'm logged into iTunes using a personal account, but logged into game center using a test account.
From what I can see, when the device is using the same login for iTunes, iCloud and game Center, there are no problems. But, when I try to mix-and-match the accounts for whatever testing I need to do, then I randomly get error 6.
There doesn't seem to be anyway to recover from this, except to have the user re-login into game center. Of course, there's no way to present the login view controller again, so the only option is for the user to leave the game, kill it off, and star up again (which re-starts the game center authentication process). I trap the error now, give the user a message saying Game Center has logged them out, and explain what they need to do about it.
But as I said, when I stopped mixing up credentials on the device, the problem went away.
BTW, on a slightly related topic, I've come to view the .authenticated property as completely unreliable. It will be TRUE in conditions where you do not actually have connection to Game Center. I opened a bug on this, too. Apple closed it saying this was working as intended by using "cached" data. Thus, it will report authenticated when it's not authenticated and give you access only to outdated match and leaderboard data which had previously been saved locally.
I have a Game Center game that allows players to make multiple moves per turn. In iOS 6, Apple implemented a great feature in saveCurrentTurnWithMatchData that allows you to do just that- it saves the data to game center to prevent cheating by repeatedly redoing a move for instance, without advancing to the next player.
The problem is, I have discovered that this actually triggers the same Push Notification taht gets sent when the player does end their turn. So other players in the game will see a badge on the app's icon and mistakenly think it's their turn when it isn't.
Has anyone found a workaround for this? Any way to call saveCurrentTurnWithMatchData without sending a push notification? If not, this seems like a design flaw that should probably be brought to Apple's attention.
I agree, this seems like a design flaw. I am also developing a turn-based game whereby a player can take several actions before passing control over to the next player. Meanwhile, I want other players to witness every action while they are looking at the game. If the other players are not running the app, I want them to receive a push notification only when the control is passed to another player.
Instead of using saveCurrentTurnWithMatchData:, I use endTurnWithNextParticipants: but I specify the current player rather than the next. This seems to do the trick:
NSTimeInterval interval = 86400; // seconds in a day
[currentMatch
endTurnWithNextParticipants:[[NSArray alloc] initWithObjects:currentMatch.currentParticipant,nil]
turnTimeout:interval matchData:[self packMatchData]
completionHandler:^(NSError *error) {
if (error) {
// handle error
}
}
];
In just about every example of submitting achievements to Game Center, I see this code
[achievement reportAchievementWithCompletionHandler:^(NSError *error)
{
if (error != nil)
{
// Retain the achievement object and try again later (not shown).
}
}];
Problem is, that one little comment is about 99% of the work. I've spent the last few hours trying to figure this out and it seems to be an endless set of edge cases of sending and resending and save and loading data.
Does anyone know of a nice tutorial (or sample code) on this that actually explains the hard part?
It's not as simple as just saving them to a file and loading them later. You get into trouble when you start having to retain multiple achievements and submit them later and then they all come back failed (in blocks!) and you have to save them again... quickly/safely... because the App might quit and you don't want to loose them.
I'm pulling my hair out.
I don't think you need to pull your hair out.
I think the basic model is this:
(a) Independent of Game Center, your game has a saved state (which you always need anyway, to restore the player to where he was when your game is quit/backgrounded). This state should include all the normal stuff you need to restore your game state, plus it should include flags for all of the achievements in your game.
(b) Game Center also stores all of the achievements in your game. When you connect to Game Center, you download the signed-in player's achievements. (Complications arise as to who the signed-in player is, but your question is not about that, so let's assume the "one true player" is always the signed-in Game Center player.)
(c) Whenever the player makes an achievement, first update the appropriate achievement flag in your game's saved state data. Second, try to tell Game Center about that achievement. If it works, update your copy of Game Centers achievements with the new data.
(d) If it doesn't work, you have an achievement marked in your persistent state that is not marked in your copy of the Game Center state. At various convenient times (e.g., whenever another achievement is earned, when you end a level, when your app starts, when you app quits, etc.) check if there are any discrepancies between what is in your own state vs. what is in the Game Center state. A discrepancy is an update that you need to re-send to Game Center. Try to send, but if it fails again, just wait until the next opportunity (e.g., whenever another achievement is earned, when you end a level, when your app starts, when you app quits, etc.) to try again. You will never lose the data because it's in your local, true picture of the user's state. (The only way you'd lose it is if the user uninstalls your app before you've been able to successfully get it to Game Center, but then, what can you do?)