How to handle apples feedback-service when pushing to devices? - service

I am using Apples (enhanced) push notification system for sending pns. Before pushing to all devices (18k), I run the feedback-service and remove the invalid tokens. Then I start pushing to all devices. There may be some device_tokens in my table, which may have become invalid but are not listed by the Feedback Service. The Feedback-Service lists them only after a failed-delivery attempt. (source: Apples Documentation) So do I have to run the Feedback-Service after every single push, or should I try to push all, run the feedback-service and retry from that token which has been listed as invalid (there should then be only one invalid token - the first invalid one in the table).
Any help would be much appreciated!
Thanks

I think the feedback service will not tell you about invalid tokens, but only about proper devices where your app is no longer installed.

Related

SWIFT4 - Refreshing Data From Server

I think I must be missing something. I have an app that loads table reservations on an iPad and in order to stay up to date, I refresh the main-page-ist every 15 seconds.
Instead I want to refresh the page only when there is a change. I want it to work like a push notification that tells my app that there has to be a change and that it needs to connect to the server and update, but some users are turning push notification off and i have no control over that. There must be a better solution I'm missing right here.
How are messaging apps doing this. How do viber, whatsApp facebook messengers know that there is a new message and show it immediately. I don't think they connect to the server every seconds... or do they?
I think, Silent Push Notification is the best solution for your case.
You can still catch the information in the background even user does not permit push notifications.
What you are doing is common but not advisable these days. You want to push, not pull. What do I mean? How often someone reserves a new table is random, so it could be 5 seconds or every 5 hours. In your case, if you refresh every 15 seconds it could be killing the battery and gobbling up data unnecessarily.
The better way is for you to set up a push server that, when a table is booked, your push server sends a push notification to your app. This way, whether instead of asking all the time "hey, any reservations?" your server tells you when a booking event happens.
Of course this requires more work on your part, but you will run into the same issue over and over again, so it's worth looking into how to do this.
If you're at a larger company, and only doing front end, you need to have the backend engineers build a push server for you.
This is how What's app and other apps notify you when you have a message.

Bittorrent sync approval process not working properly

I created a link to share a folder, deselecting the option that peers I invite must be approved on this device.
The other person used the link, and received a message that the "Sender needs to approve access to this folder based on these identity details".
My bittorrent sync window isn't showing me anything to indicate that someone is waiting on approval. I've never shared a folder via a link before (always just used keys directly on previous versions), so I have no idea how the program is supposed to prompt me for approval, and I can't find any documentation indicating how this prompt would be provided.
So there seem to be two problems here:
1. Even though I said the link doesn't require approval, they are being told that it does.
2. I don't have any way to approve it.
What's going on here? How do I fix this?
Thanks.
The most common cause of this is one of the systems having clock time out of sync too much, usually resetting your computers time using an online time server resolves it.

How did PUSH / APNS works?

I read a few tutorials / howtos about Apples Push Notifications, but there are a lot of information out there, so I wanna know if I understand everything correct.
Here is how I understand it:
You need a certificate for Puhs, you can get it in the development center (found very good tutorials for it)
You need a database in which the DeviceToken is stored. This you can set into the database from your application itself (found a tutorial for that I think)
When a user should get a message (e.g. gets a Private Message or something like this) you must send a PHP Payload to the apple server.
Is that all? (I know its a much longer, I only wanna know if I understand everything right).
Must I do any other thing on the client side else then save the device token to the database?
Yes you pretty much have it there. If looking at sending large volumes then make sure that you are not opening and closing the connection to the Apple APNS servers as they treat it as a DOS attack.
The payload is also not PHP but JSON.
Also make sure you read from the feedback service and deactivated device tokens and stop sending them messages.
Client side you also need to "decode/process" the payload in the various app delegate places. Essentially it is a discretionary and you can send custom info as part of the APNS payload.

Updating iPhone Reachability on Network Changes

Edit 23.5.11
I'm now wondering whether I'm over engineering this. When I use an online connection, I handle it properly - either:
in the background with a progress or activity indicator showing and if it fails, I display a suitable message OR
I call another application, either Safari or Maps which will then do its own check and fail if there is no connection. That leaves the user in that other app that has failed, which is not perfect tho.
So if I do what I'm suggesting below and standard Reachability returns not reachable and I then have to do a NSURLConnection in case the radios have gone to sleep, then I'm not sure that's any better than just trying to get the online resource in the first place.
If anyone can help - I'd be really grateful. I'm almost ready to submit, just need to get this right.
I'm using Apple's Reachability sample to generally good effect except for when the mobile or cellular connection goes to sleep and then comes back or the wifi goes and the cellular connection is then relied on.
Its fine when the mobile (cellular) connection isn't changing. This is in line with comments I've read, that when the cellular radio switches off you have to wake it up again manually. However, I can't see how to do that.
Do I need to setup a NSURLConnection? Some sample code would be great. When I get a notification that there is no connection, would I send the NSURLConnection and tell the user to try again in a moment and then if I get a callback to say its successful, override the off setting from Reachability?
In addition, would I need to do that whenever there seems to be no connection, just in case its that - this seems wasteful of resources when it may well not be that. e.g.an iPod Touch that's not in wifi reach.
I've also looked at DDG's alternative, but it looks like that will have the same issue.
Any helpful suggestions would be warmly welcomed.
Thanks,
Chris.
You cannot and should not use Apple's Reachabilty sample code (or the SCNetworkReachabilityFlags) to determine if a network resource is or will be available. They give you useful tools for giving user feedback about why a connection failed and for determining if and when to retry a connection. However if you want to access a network resource you should just ask for it.
Don't present your users with "no network connection" alerts based on the reachability flags. Perform your network request and if it fails check the reachability flags and your own history of requests to see if you should tell your user that the request failed or silently retry. You shouldn't want or need to spam the user with every network failure. If a request fails consider retrying it if the host seems to be reachable and only report a failure to the user after a couple of attempts or when the reachability flags suggest that you have actually lost your network connection and not just had a single request fail.
As for reactivating the device's radios you'll need to balance your desire to try to fetch network resources with allowing the device to power down the network interfaces to save power. I don't know what your app is trying to do but I'd recommend allowing the device to power down and then trying to connect in response to a user asking the app to fetch new data. I don't see a case where you would want to reactivate a radio just to give the user a hint that some network resource may or may not currently be reachable.
See https://devforums.apple.com/message/409618
The only way to know whether a host is available is to try to connect to it. If that connection fails, you can use reachability to provide feedback to the user, and to guide your retry mechanism, but using reachability to preflight a connection is not a good idea.
The key issue here is that reachability uses local information to determine its results. This doesn't say anything about the state of the wider Internet. The origin server might be down, or any number of links between you and the origin server might be down, and reachability will happily say that it's reachable. At that point you're going to try to connect, and the connection will fail. So you're going to have to handle the error anyway, which means you might as well not do the preflight and let your standard error handling cover this case as well.
Also take a look at this question regarding checking for a resource before loading it using an external application: https://devforums.apple.com/message/411329
Making a HEAD request for the resource should give you a reasonable idea if the external app will be able to load it without requiring you to download a significant amount of data (latency will still be a concern though).

How would you keep secret data secret in an iPhone application?

Let's say I need to access a web service from an iPhone app. This web service requires clients to digitally sign HTTP requests in order to prove that the app "knows" a shared secret; a client key. The request signature is stored in a HTTP header and the request is simply sent over HTTP (not HTTPS).
This key must stay secret at all times yet needs to be used by the iPhone app.
So, how would you securely store this key given that you've always been told to never store anything sensitive on the client side?
The average user (99% of users) will happily just use the application. There will be somebody (an enemy?) who wants that secret client key so as to do the service or client key owner harm by way of impersonation. Such a person might jailbreak their phone, get access to the binary, run 'strings' or a hex editor and poke around. Thus, just storing the key in the source code is a terrible idea.
Another idea is storing the key in code not a string literal but in a NSMutableArray that's created from byte literals.
One can use the Keychain but since an iPhone app never has to supply a password to store things in the Keychain, I'm wary that someone with access to the app's sandbox can and will be able to simply look at or trivially decode items therein.
EDIT - so I read this about the Keychain: "In iPhone OS, an application always has access to its own keychain items and does not have access to any other application’s items. The system generates its own password for the keychain, and stores the key on the device in such a way that it is not accessible to any application."
So perhaps this is the best place to store the key.... If so, how do I ship with the key pre-entered into the app's keychain? Is that possible? Else, how could you add the key on first launch without the key being in the source code? Hmm..
EDIT - Filed bug report # 6584858 at http://bugreport.apple.com
Thanks.
The goal is, ultimately, restrict access of the web service to authorized users, right? Very easy if you control the web service (if you don't -- wrap it in a web service which you do control).
1) Create a public/private key pair. The private key goes on the web service server, which is put in a dungeon and guarded by a dragon. The public key goes on the phone. If someone is able to read the public key, this is not a problem.
2) Have each copy of the application generate a unique identifier. How you do this is up to you. For example, you could build it into the executable on download (is this possible for iPhone apps)? You could use the phone's GUID, assuming they have a way of calculating one. You could also redo this per session if you really wanted.
3) Use the public key to encrypt "My unique identifier is $FOO and I approved this message". Submit that with every request to the web service.
4) The web service decrypts each request, bouncing any which don't contain a valid identifier. You can do as much or as little work as you want here: keep a whitelist/blacklist, monitor usage on a per-identifier basis and investigate suspicious behavior, etc.
5) Since the unique identifier now never gets sent over the wire, the only way to compromise it is to have physical access to the phone. If they have physical access to the phone, you lose control of any data anywhere on the phone. Always. Can't be helped. That is why we built the system such that compromising one phone never compromises more than one account.
6) Build business processes to accommodate the need to a) remove access from a user who is abusing it and b) restore access to a user whose phone has been physically compromised (this is going to be very, very infrequent unless the user is the adversary).
The simple answer is that as things stand today it's just not possible to keep secrets on the iPhone. A jailbroken iPhone is just a general-purpose computer that fits in your hand. There's no trusted platform hardware that you can access. The user can spoof anything you can imagine using to uniquely identify a given device. The user can inject code into your process to do things like inspect the keychain. (Search for MobileSubstrate to see what I mean.) Sorry, you're screwed.
One ray of light in this situation is in app purchase receipts. If you sell an item in your app using in app purchase you get a receipt that's crypto signed and can be verified with Apple on demand. Even though you can't keep the receipt secret it can be traced (by Apple, not you) to a specific purchase, which might discourage pirates from sharing them. You can also throttle access to your server on a per-receipt basis to prevent your server resources from being drained by pirates.
UAObfuscatedString could be a solution to your problem. From the docs:
When you write code that has a string constant in it, this string is saved in the binary in clear text. A hacker could potentially discover exploits or change the string to affect your app's behavior. UAObfuscatedString only ever stores single characters in the binary, then combines them at runtime to produce your string. It is highly unlikely that these single letters will be discoverable in the binary as they will be interjected at random places in the compiled code. Thus, they appear to be randomized code to anyone trying to extract strings.
If you can bear to be iPhone OS 3.0-only, you may want to look at push notifications. I can't go into the specifics, but you can deliver a payload to Apple's servers along with the notification itself. When they accept the alert (or if your app is running), then some part of your code is called and the keychain item is stored. At this point, that is the only route to securely storing a secret on an iPhone that I can think of.
I had the same question and spent a lot of time poking around for an answer. The issue is a chicken and egg one: how to pre-poluate the keychain with data needed by your app.
In any case, I found a technique that at least will make it harder for a jailbreaker to uncover the information - they'll at least have to disassemble your code to find out what you did to mask the info:
String Obfuscation (if the link breaks search for "Obfuscate / Encrypt a String (NSString)")
Essentially the string is obfuscated before placed in the app, then you unobfuscate it using code.
Its better than doing nothing.
David
EDIT: I actually used this in an app. I put a base coding string into the info.plist, then did several operations on it in code - rot13, rotate/invert bytes, etc. The final processed string was used to decode the obfuscated string. Now, the three letter agencies could for sure break this - but at a huge cost of many hours decoding the binary.
I was going to say that this is the best technique I've come across, but I just read Kiran's post on UAObfuscatedString (different answer), which is a completely different way to obfuscate. It has the benefit of no strings saved anywhere in the app - each letter is turned into a method call. The selectors will show up as strings, so a hacker can quickly tell that your class used that technique though.
I think that this similar question, and my answer, may be relevant to your case too. In a nutshell, there was some talk of a trusted platform module being present in an iPhone. This would allow your service to trust an iPhone, even in the hands of an attacker. However, it looks like using the keychain is your best bet.
Did you consider/try the Push Notification suggestion, for initially transmitting the secret to the app & keychain? Or end up finding some other method to achieve this?
I'm going have my iphone app upload images to Amazon S3. Instead of putting the AWS credentials in the app, I am going to have the app phone home to my server for the URI and headers to use in the S3 upload request. My server will generate the S3 URI, proper signatures, etc. I can then implement a tighter, more specific security model on my app's webservice than AWS offers by itself and not give away my AWS keys to anyone with a jailbroken iphone.
But there still has to be some trust (credentials or otherwise) given to the app, and that trust can be stolen. All you can ever do is limit the damage done if someone jailbreaks an iphone and steals whatever credentials are in the app. The more powerful those credentials are, the worst things are. Ways to limit the power of credentials include:
avoid global credentials. make them per-user/application
avoid permanent credentials. make them temporary if possible
avoid global permissions. give them only the permissions they need. for instance, write permissions might be broken down into insert, overwrite, delete, write against resource group A or B, etc, and read could be broken into read named resources, read a list of all existing resources, read resource groups A or B, etc.
I would recommend creating a key at run time if possible. This way if the key were to get apprehended during a particular session, once the session ends, the key will be worthless. They could still apprehend the key from memory if they are smart enough, but it wouldn't matter since the key would become invalid after a period of time.
Sounds wonky. Would use HTTPS and maybe an encryption package to handle the key.
I think CommonCrypto is available for iPhone.
EDIT: Still sounds wonky. Why would anyone pass a secret key in an HTTP header? Anyone who traces your network traffic (via a logging wifi router, for instance) would see it.
There are well-established security methods for encrypting message traffic...why not use them rather than invent what is basically a trivially flawed system?
EDIT II: Ah, I see. I would go ahead and use the Keychain...I think it is intended for just these kinds of cases. I missed that you were generating the request using the key. Would still use HTTPS if I could though, since that way you don't risk people deducing your keygeneration scheme via inspection of enough signatures.