How to implement user suspend feature in iOS - ios

In an iOS application, When I detect a users improper action (for example posting violent content), I wan't to suspend the user from using my application. The basic idea to implement this feature is to create and save an unique id for each application installs and suspend the usage from server api's.
My question is, how can I implement this feature even if the user re-installs the application, and still pass the Apple's iTunes submission?
I came up with two ways to technically implement this feature, but wondering how Apple would respond.
Store the IDFA (I understand that users can reset the id on their behalf)
Store an app generated udid to the Keychain (which should not be deleted even if the user deletes the app)
I know there are no perfect answers, but would appreciate to discuss this issue with anyone that have tried submitting a similar application, or anyone that is well aware of the Apple's guidelines. Thank you.

Apple will reject apps that inappropriately use the IDFA.
If your app does not use server login (at which point, whatever flags you require could be delivered to the client), keychain storage would be the only real solution.
However, if you don't use server login, you block the device, not the user. Is this your intent?
BTW, without server login, a determined user can still get around keychain storage: Reset keychain on the device

You can block a given account. Most people these days key an account with an email address. Some require a credit card (Facebook fully validates accounts using credit card numbers), others require a bank account (PayPal has to send money somewhere!) and it is growing in popularity to request a phone number (Twitter is getting there). In the end, to really be effective, you have to block something that is difficult to produce.
With email, your users can always create a new account. Check out mailinator.com. Alternatively, all you need is one domain to have as many email addresses as you want -- I use five different email accounts daily, and I use about two dozen more on a monthly basis.
Installation ids are ok but users can always just uninstall/reinstall. And if you do manage to get a device-identifying number (easy to do really, even in the post-UDID era) so that you can block a given device, your users can just get a new device, or hack your app to use some random value, or spoof your API with cURL. I own three iPhones, two iPads, two Samsung tabs, three other Android phones, two Mac Book Pros, a mini, two PCs, and I run three virtual Linux boxes, and one virtual XP box. And what happens when somebody sells a blocked device to a non-abusive user?
So just block the user's account, keep excellent log files, and keep fighting the good fight.

Related

How can I distribute an iOS app to 50k users by invitation only?

I have a client who wants to deliver the app to 50k specific users, at start. Then he wants to go public with the app after some time. However, this could not be seen by users as beta testing, since it's just an "exclusive" earlier possibility to access the app, not tests.
We know these users since they are a part of other service users group. We will probably create accounts for them and distribute login/one-time-passwords by invitation or give them the possibility to log in with credentials from the other service.
I've been searching for the solution (e.g. https://www.knowband.com/blog/mobile-app/share-ios-app-without-publishing-on-apple-app-store/) but still, I'm not sure which way to go. We're still in the middle of development so we can provide a possible solution and even make changes in the onboarding/login process. But we have to have a decision on this matter.
From possible solutions:
AppStore - we would not give the possibility to register in the app and just people with credentials could log in. But is it even possible with an iOS app and not be rejected by Apple? I know that many apps don't have registration within the app (e.g. banking apps) - how do they do that? They just say that registration is available only on some www/in person at the bank and you receive credentials to your account somewhere else?
Enterprise distribution - this is probably not possible since users won't be employees of my client. These are regular people.
VPP - I've heard about it recently and never tried it but isn't it just a "simpler" Enterprise solution and shouldn't users be also employees of my client? Can VPP apps be changed to regular AppStore apps afterwards?
I think right now option 1 seem the most possible one since the app will be distributed to all the users after some time (we will add registration then). Any ideas on the matter? How can we not be rejected using solution 1 during a review?
Solution 1 is possible, you provide apple with certs in App Store connect when you submit to the store. Specifically the field 'Sign-in required'
I would do that, it's got very little time overhead as compared to the other two.

Invite person from contacts who doesn't have app?

I want to let users of my iPhone app invite people from their contacts to a group they're creating. I can use deeplinks for people that already have the app installed to have an invitation automatically show up, but I was wondering if I can somehow pass custom information to someone downloading the app for the first time so after they initially open the app they'll have an invite waiting.
As far as I can tell this is impossible but I was wondering if there's any other way to somehow associate a contact with that person making an account on their own device. My application uses gmail authentication for account creation so if everybody had each other's gmails saved in their contact this might be possible, but that's not the case unfortunately. If I could get a user's phone number then it would be easy but I know that's not allowed without specifically asking the user.
Does anybody know if it's possible to do something like deeplinking for people installing the app for the first time?
You can do this with Google Firebase Dynamic Links. Google has a guide for this here:
https://firebase.google.com/docs/dynamic-links/
If I understand the question correctly, here is what I'd do:
Scenario: Send Invite
If the email invited by a user is a registered email, done.
If the email invited by user is not a registered email, store it in a separate table (pending invites)
Scenario: Sign up/ Sign in
User registers using email, store user information.
When the user logs in, check if email exists in pending invites table, if exists, present invitation.
Delete user from pending invites table
Not sure if you have it already but you might need a db table to keep the invitations sent by your users.
What you're describing is called Deferred Deep Linking (Deep Linking refers to using a link to open your app directly to a specific piece of content, and Deferred means that it works even if the app isn't installed first).
As you noted, there's no native way to accomplish this on either iOS or Android. URL schemes don't work, because they always fail with an error if the app isn't installed. Apple's newer Universal Links in iOS 9+ get closer in that they at least don't trigger an error if the app isn't installed, but you'd still have to handle redirecting the user from your website to the App Store. You can't pass context through to the app after install with Universal Links, so you wouldn't be able to present the invitation. Additionally. Universal Links actually aren't supported in a lot of places.
To make this work, you need a remote server to close the loop. You can build this yourself, but you really shouldn't for a lot of reasons (not the least of which being you have more important things to do). Free services like Branch.io (full disclosure: Branch is so awesome I work there) and Firebase Dynamic Links are designed to solve exactly this requirement, and can handle all of the backend infrastructure for deferred deep linking so you don't have to. From your perspective, as the developer, you'll seamlessly get exactly the same data to work with whether or not the app was installed when the link was clicked.

Handling authentication for multiple apps under the same account - iOS

Working for a company where we are starting to have many small apps, each with their own log in screen.
So that means whenever someone's password changes, they'll have to re enter their password for every app
Can be cumbersome to the user, especially when our policy is to have user's passwords change every 3 months and there are 6 or more apps to enter the password on
Has anyone come up with a work around for this problem where the user would only have to enter their password once? I'm thinking I could have one dedicated app solely for authenticating and then do some kind of interprocess communication if that's even possible
Again, doing this for iOS. I know on Android it wouldn't be an issue because developers can add accounts in the settings screen. However, iOS is a different beast
*Note these are enterprise, in house only apps. Not public facing on the app store
You need to store the username/pwd on keychain and share them between apps as mentioned here
https://developer.apple.com/documentation/security/keychain_services/keychain_items/sharing_access_to_keychain_items_among_a_collection_of_apps

How can I limit ios app purchasers to one account?

I want to create a social networking ios app which costs money, and when the user buys it they are allowed to create only one account on the app. So the purchase is associated with the account somehow... or the app has a specific id on each device its bought on... would I need to use gamecenter somehow...
How would I approach something like this?
Any help would be greatly appreciated.
First of all, more than one person may use the device (think a family with an iPad) so what your doing is inherently a bad idea.
That said, you can use an in-app purchase to let them buy account access - check with the server first to make sure a desired username is available, then let them use an in-app purchase to buy access, and on your server tie that purchase ID to the user name. Even if they deleted the app and tried to re-purchase (while logged into the same iTunes store account) it would see a purchase had been made and essentially be the same user. It even does kind of work with multiple users as they could switch iTunes accounts (though that is a pain).
I would also suggest trying to tie it to the users iCloud account in some way, which is easier for users to switch between on an device (a family might use one iTunes account but have separate iCloud accounts).
If you don't want to give Apple 30% of the registration fee, your only option is to have users sign up on the web and pay there, then have a login they can use in your app. Then it's a matter of trying to prevent duplicate logins on you server, although as a last point of thought, I can't remember a business that succeeded by refusing people's money.
You could generate an unique id on the phone, store it in the keychain, and use that to communicate with the server.
Since you are creating your own account management system, just save the user information once they do the account creation bit and never show the option again. Because developers no longer have access to the device id, you may have problems identifying an existing user if they delete and re-install the app, but I am not sure that there is a solution to that problem.
Edit: As a commenter to this question mentioned, you can save things to the keychain. Check out this link for a good lib for modifying the keychain.

How to register user and maintain in-app-purchase state on my server

I'd like to have a user register with email and password so that I can provide his in app purchase in my android app / web site and PC software. (Its a download from my server)
1A) Would you force the user to register?
Or 1B) Allow him to skip registration if he wants and the purchase will only work on Apple devices.
And 2) How would you prevent someone from re-registering multiple emails on the same device through Apple's restore purchase feature and then allowing their friends to sign in with those emails and get things for free?
EDIT - In 2) I hear all the time people say store the receipt on the server and then check it, but I've never seen code. Also when you restore purchases the receipt is not the same so I'm not sure how you'd know to prevent the user from registering multiple emails across restores purchases. I'm looking for code(pseudo?) from anyone who has implemented receipt checking on the server.
I would go with B and let them choose. After all, if they aren't going to use the Android, web nor PC versions, why should they have to give you their email address?
Personally, I wouldn't stop people from re-registering with multiple email addresses. Yes, some people will take advantage of it, but at the end of the day, most of those people would not otherwise have paid for it, so you haven't really lost sales. See http://torrentfreak.com/piracy-is-theft-ridiculous-lost-sales-they-dont-exist-says-minecraft-creator-110303/ for more information.

Resources