I'm new to iOS passbook development and I'm having trouble defining the limitations of the service. I'd rather not jump into several hours of dev work that I don't have time for without knowing it will work.
End Goal:
A user is walking to a particular location and receives a pass with their member barcode on it.
Question:
Is it possible to create this pass from my iOS app under these assumptions without any other web service or push notification involvement?
The user's barcode number is passed in via a web service after first
running the app.
The location coordinates are also sent in the same way.
There are 20+ location coordinates.
#1 and #2 are addressing the dynamic abilities of pass creation from an app. I'd like to know to what extent I can create a pass with a very specific member barcode that comes from the web services in the app itself.
#3 addresses the issue that a pass can only have 10 locations and I'm curious how to solve that issue. I suppose I could make 3 different passes (10 locations, 10 locations, X locations) but then wouldn't the user potentially have 3 passes in the passbook for what is essentially the same feature?
Apple says pass creation needs to be done on a server, not on the device. The process involves signing the pass data with your pass certificate and you should not distribute that to devices.
I don't know how to answer your #3 question.
Related
I'm writing an application which will be used in an enterprise, no outsiders.
This application should fetch data from API response and display it.
Each user has his own device, Ipad and should see only the data he is the owner of.
Problem i'm facing is identifying the device/user, so that API responds with only the information the user is supposed to see.
brief example of how it should work:
App is opened -> get unique id -> attach ID to API call -> receive appropiate response -> display data
As i imagine this ID should be static and not made upon installation of the app or generated.
I've tried getting UDID, Serial, MAC,- no luck, they're deprecated. Only managed to get .IdentifierForVendor, which is unique not in the way that i need.
So here is my question, are there any other options left?
Like fetching appleID name,email or should i make unique deployments for everyone separately?
Or a Log-in screen?
You could create a GUID for every App instance. However, apart from that you will have a hard time doing what you want.
These ways of identifying a device have been deprecated to ensure Advertisers and other malicious Apps cannot fingerprint a device easily.
If you don't want too much hassle authenticating everyone, you could apply a simpler scheme such as using a pin code, QR code, NFC tag or whatever you prefer.
However, if someone were to steal one of these enterprise devices and it would contain any secret information I would rather rely on something more secure as username and password, or even better something multi-factor.
Unique id's will have to be set by deploying the app from MDM. For example:
https://docs.jamf.com/9.9/casper-suite/administrator-guide/In-House_Apps.html
How should the application accept those variables, i dont know. Maybe it modifies .plist when deploying.
Solution i did was enforcing device name from MDM, so that users are unable to change it - and using that as the unique identifier.
We're trying to implement deferred deep linking in one of our iOS applications to encourage users to invite their friends to use the app, and reward users based on how many installs occur from their referral link. Basically similar to TapStream's product.
Consider this example:
So, UserA shares their link, “ourappURL.com/refer?id=userA”, on any
network they want. UserB clicks that link, which will take them to
Safari and then bounce them to the App Store page where UserB
downloads the app.
When UserB opens the app, the app checks which referral ID they came
in on (if any). In this example, the referral ID would be “userA” as
that’s the ID that was in the referral link. The app then sends this to
our servers and we award UserA with a referral credit.
I'm trying to break this issue down into its core parts. I believe the first part is getting the web page for the user's referral link to save the referral ID to the device somewhere that the app can access it. But I'm not sure this is possible because of the sandboxed nature of iOS.
I know this is fundamentally possible because many ad providers offer the ability to track installations from an ad campaign (see Mobile App Tracking for example).
We have also attempted to do this ourselves and I will try to break down the different steps here.
Going back to your example, you are correct about "remembering" the device identification, and all relevant data "id=userA". You are also correct about "sandboxed nature of iOS" which I presume it means a web page is not allowed to store information outside of the browser app (Safari) and apps (your app) are not able to access information stored by other apps (Safari).
Our solution to this is to store this device to data key-value pair in an environment that is both accessible by the browser as well as by your app, i.e. your backend server.
The next challenge, which remains to be the biggest challenge, is how to uniquely identify this device from the information collectable from the browser? Javascripts in browsers, unlike native apps, don't have access to IDFAs which could be used to uniquely identify a iOS device. To overcome this, one can imagine to use a combination of common information that is available both to the browser app as well to your native app, i.e. OS type, public IP, screen size, etc. etc. Please note, a composite key from these data fields does not guarantee uniqueness (imagine two iPhone 6 visiting this web page via the same router). Therefore, your backend server (assuming you are using it to store this key-value pair), will want to have a strategy on how to handle collisions on keys i.e. the second key deletes the first key, or you allow collision to exist by having a queue of values for a single key. This really depends on how you actual plan to use this technology.
The last step is to form this composite key on your app using the exact same fields you used earlier in the browser to perform a "lookup" on your backend server to retrieve the value previously stored.
Here is a summary of the steps:
User 1 invites User 2 by sending the following link to 2: example.com?inviter=1
User 2 visit Web Page P
P constructs and sends the following key-value pair to your server S iOS|55.55.55.55|750×1334 -> inviter_id=1
User 2 goes to the app store and downloads your App A
User 2 first launches A, A contacts S with the same key (assuming the IP hasn't changed).
S finds the value inviter_id=1 by using this key passed in and, let's say, reward User 1 five points for inviting 2.
Hope this help!
Edit 04/24:
Since Derrick mentioned it in the comments, I figure I would take this chance to finish our story here.
Going back to the beginning of my answer where I mentioned we've attempted to do this ourselves. We had a working prototype based on our current system architecture (which is not in anyway optimized, or meant to be optimized, for storing and analyzing deep link data like this), we ultimately decided not to allocate any additional engineering resource into this project.
Due to the heuristic nature of this matching process, we found this project needing debugging, tuning and optimizing constantly for a diminishing ROI. More importantly, we have found other companies which are more specialized and do a much better job than ourselves.
It has been probably 6 months since we stopped using our internal system and we haven't regretted making such decision.
During this processes, we've worked with a number of vendors, Appsflyer, Adjust, TapStream and we have ultimately ended up with Branch Metrics https://branch.io.
Whether you should DIY or work with another company again depends on your specific objective. We finally decided to stay with Branch, not only because the other vendors charged anywhere from $500 to thousands of dollars per month while Branch is completely free, but also the level of the support they have provided is simply unparalleled.
We've successfully used the clipboard (NSPasteboard) to achieve this: the web page that processes the redirect to the app store does a paste to the mobile device's clipboard before letting the user download the app. Once the app is installed, it uses NSPasteboard on first launch to check for an appropriately coded string. This string can contain the text of interest or, more securely, a token used to fetch interesting data from the backend. In Objective C:
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
NSString *pasteboardString = pasteboard.string;
The clipboard can be cleared once the app is done with it, to avoid repeating the same action.
There is a good solution here: http://blogs.innovationm.com/deferred-deep-linking-in-ios-with-universal-link/
Basic workflow:
User selects domain link on web.
Link sets referral ID to cookie.
User redirected to app store.
On app launch, load referral page in SFSafariViewController.
Referral page checks for cookie and if it exists calls a deeplink into the app with the referral ID.
My answer from HERE
Apple no longer supports Deep Links. It is now called Universal Links and works a bit differently.
Source
Now that Apple no longer supports URI schemes for deep linking, developers must implement Universal Links in order to deep link properly on iOS. If you are already using URI schemes, check out our blog on transitioning to Universal Links.
From: HERE
And HERE is another article on Universal Links and what they are.
I have a question which I have not been able to figure out so I decided to see if I can get some help on here.
I am working on an iBeacons project and I have been able to understand the basic function of iBeacons, setting up UUID'S and major and minor id's to specify exact notifications, but my question is how do I dynamically update information I send out to the users without having to go into the code each time to do this. Do I need to create a database to store all my information I want to push out to users? if so how will this database constantly refresh messages pushed out to users? An example would be lets say if you walk into a store and you get a notification in the shoe section saying there is a 10 percent off, you look at the notification but not too impressed and start to walk out, then you get another notification saying for today only you can get a 25 percent off... The app has to dynamically refresh for this to be possible.
Please help me clarify this
Thank you very much for the help
What you probably want is to store this deal information in a web service so you can update it without changing the app. Your app would need to download the updated deal information from the web service either when it starts up or when it sees an iBeacon.
My company, Radius Networks, offers a tool called Proximity Kit that makes this easy. You can assign arbitrary key/value pairs to iBeacons using a web interface. Then your app downloads them automatically an has access to them whenever you see iBeacons.
In your scenario, they key/values could be something like:
primary_offer_text=10% off all shoes
secondary_offer_text=20% off all shoes
I have an app that is uniquely branded for each customer (think restaurants, etc.) I need to have the user be able to click on a link to my server that contains a unique code, stores that temporarily on the iOS device (cookie, etc.) and then directs them to the app store to download the app. Then when it is downloaded, the app grabs that cookie or temp. data on launch and brands the app for that customer. I know this is possible on Android, but is it on iOS?
Downloading the app first and then selecting the brand (or restaurant) is not feasible in this case, as the url wil be shared with other customers of the same business and we want to create a fluid experience, where they won't be able to "see behind the scenes" and choose a different branding.
Thanks
Edit
Thank you for all the replies. We've reevaluated and are considering having the url be opened on the device and grabbing the IP address or another unique id, and saving that along with the correct brand to a database. The app will then connect to the database on launch, and if the IP's match, will brand accordingly. We're looking for a more reliable identifier than IP, however. Now that UDID is deprecated, are there any other identifiers we can use?
I think the design you propose of a webserver link creating the code that needs to be read by the iOS app later is the issue. You should have a solution that is entirely app based. Perhaps you can have the same services on the website be available as one app which then sets up the code in pasteboard. The user then launches the actual app that looks at the pasteboard and skins itself accordingly.
That being said, data can be shared between apps from the same app seed ID by using UIPasteboard in addition to a few other ways.
I use the pasteboard to share info between apps quickly and easily using this class.
You can use identifierForVendor (UDID replacement) to identify individual devices. Are you planning on harvesting those identifiers prior to the end user "registering" the device at the final location? If not you'll never be able to determine which device belongs where.
What about having the end-user logging into your server as that restaurant? It can be a somewhat generic login per restaurant like "Wendys/Wendys5?" and "McDonalds/McDonalds7!" to determine their App Store URL. As long as the password is easy and non-programmatic to guess it would be unlikely they figure out how to register as a different restaurant. You could also do a simple restaurant selection screen coupled with a password specific to each chain but this would expose the user to which other restaurants are using the app. This way you won't have to continually add IPs if they expand locations and can revoke credentials if the login is compromised.
One question, though: Do all of your clients understand that they'll have to have an AppleID tied to each device? You can only shared a single AppleID across 20 devices.
Not exactly a programming question but here it goes:
How can a company who is distributing passbook passes via email or web prevent a pass from being installed on more than one device?
I can not find anything about this on Apple docs. The only I can think of is to check on the device registration webservice whether the combination of pass type and serial has a device already registered and delete it , but I am not aware of any command to delete the pass remotely.
Another option would be to check if it is already registered prior to generating the pass but this would only work for URL distribution, not for email.
Is there any way to delete a pass remotely via push notification + update? Any ideas on how to solve this issue?
Mail and Mobile Safari will present any pass they are given and the user can decide to add them to their Passbook. There is nothing the pass creator can do to prevent it except to be careful about how the .pkpass files get handed around.
If you really only want to deliver a specific pass to a specific device you might consider a companion app that uses a custom API to communicate with the the backend and request the pass for that device that way. Then you have much more control than distribution via email or url links.
Apple frowns on trying to delete a pass programmatically; only users are supposed to delete passes because they added them. You can, however, update a pass to make it clear that is not valid and should be deleted. For example you can remove the bar code, if any, and use a background image with a big red "INVALID" on it.
Just to extend #ohmi's answer:
You cannot prevent passes from being installed on more than one
device - e.g. if user enables iCloud for Passbook, the passes will get
synced automatically across devices.
Considering your links to pkpasses are public, you may want to consider
introducing one-time download links, but while it can fill your
needs just fine, users can be really disappointed if it's impossible to re-add
passes that they manually deleted. So I wouldn't recommend such solution.
You can make you pkpass links kind of private, so only GET request originating from your application and carrying a specific value for specific header field (e.g. auth_token), will receive a pkpass file, however this way you almost disable pass distribution via email or via sharing URLs to passes and make pass updating probably impossible.