I am trying to share records between users on CloudKit but I'm having trouble allowing users to accept shares. When a user opens a share on their device, their status on the share continues to show up as "invited" rather than switching to "accepted." The UserDidAcceptCloudkitShare function does not get called.
Am I wrong to think that opening a share is equivalent to accepting? If so, what is the trick to having a user accept a share?
Please excuse my ignorance, as I'm new to CloudKit and iOS in general. Thanks.
Related
I'm working on an app that uses CloudKit sharing functionality. The sharing features have been working great, but recently I no longer get the user names back from the CKShare.Participant when a user accepts the sharing request.
Details
I'm using the built-in UICloudSharingController to set up the share, which works and sets up the share properly.
When the invited user accepts the share, the owner gets a notification of the change in the zone and then fetches the CKShare.
The fetched CKShare object has an array of share participants (CKShare.Participant), which has a nameComponents property. I've used this in order to get the first and last name of the participants to display in the UI. This was all working fine until recently.
Now, however, I'm only getting values in nameComponents for the owner of the share. The accepted participants have nil values for the nameComponents.givenName and nameComponents.familyName.
I have not changed anything in this part of my code in some time, so don't think I've caused this. I've tried this on iOS 11, 11.4, 12, 12.1 and all have the issue. This leads me to believe there might have been a change on the server side from Apple.
Note
I am not requesting .userDiscoverability permissions. I have not had to do that in order to get the names once a user accepts. I realize that I can request that and then use CKDiscoverUserIdentitiesOperation to get the names. But I'd rather not as I don't want the dialog, which is confusing for users.
Has anyone seen this change? Or better, yet, does anyone have any suggestions for tracking down the cause or fixing it?
Thanks.
I am currently working on an app that is going to use the users iCloud information, namely first name, last name and e-mail address as a way to automatically sign-up for the app, instead of filling out a huge form.
Currently the only way I see to get to this information, is to ask the user for permission using the only CloudKit permission type available (userDiscoverability).
CKContainer.default().requestApplicationPermission(CKApplicationPermissions.userDiscoverability, completionHandler: { (status, error) in
....
})
The problem with this is, is that the definition of userDiscoverability is:
The current user is discoverable (through the user's email address) to
other users of the app
Which leads to the default dialog shown here:
The problem is, is that I want access so that i can use the information above to sign someone in automatically (and use it for when someone changes devices, loses their device, etc) so that they don't have to sign up again. Therefore the dialog shown here isn't relevant to what I need it for and the users of the app are going to be confused as to why other users of the app will see that they are using the app(and in fact there is no functionality in the app to allow this at all anyhow).
Like other privacy entries available in Xcode, is there one available somewhere for CloudKit where I can add my own custom message so that I can customize the reason I need permission?
I know that others people have offered solutions, like providing your own custom dialog before the system asks or providing a Page View Controller to explain what's going on but I would like to avoid that. Apple really needs another permission type here but for the time being, thats all we have.
Suggestions/Comments/Feedback welcome.
I am developing an mobile app for iPhone. The app will primary used by people who are on holiday in a different country and will be offline most of the time, due to high costs for internet traffic.
However, the company for which I am developing the app wants to users to be able to use the "Facebook Share" functionality also when people are not connected to the internet.
It should work on a way that they click the SHARE link button in the app, but then get a message that they are offline and the link will get shared as soon as they are online again.
I am trying to figure out how to do this. Can I pass the link I want to share to the official FB App via fb:// protocol (or whatever) and the FB App handles the post/share as soon as it is online again?
Or do I have to do it on my own, put the links I want to share in a internal database and then post them to the wall when I am online again?
Or any other ways??
Any suggestions would be welcome, I would prefer a very quick solution and hope someone maybe has an idea how to do this. I was hoping I can pass the share-link to the official FB App and this one handles everything when it goes online again !?
Thanks for your ideas!
Your approach should be to make your link-sharing code automatically cache requests until they are sent. The app then doesn't need to concern itself with the details - it can just post the link and get a 'failed', 'success', or 'postponed' response from your API and notify the user accordingly.
Your link-sharing code can then internally check if it can currently post to FB and if not (either because the user is currently offline or perhaps the Facebook token is expired) it will store it for later. This class will then re-check periodically (for example when the app comes to the foreground or when the class is initialised the next time the app starts) for connectivity and then it will check if the token is still valid and perform FB login if required. Once it has a valid token it can then iterate through the pending requests and act upon them.
If you really want to make it nice and clean, you can separate out the code that accepts incoming requests to do something, checks if it can be performed now, does it or stores it for later, and periodically checks any requests in the pending queue. This class will not have any idea what the requests do or how they are performed, it will work with another class that implements a protocol to do the actual work and knows about facebook, etc. There may even be an existing design pattern for such a setup, but I don't know what it's called if there is.
Update: I did some research and found this is very similar to the "Fire-and-Forget Pattern".
After registration, our app prompts users to invite her friends (aka phone contacts) to use the app too. This allows us to send an email/sms to the useer's contacts with some sort of invitation key. Works fine for a web version app, just embed the key in the url you provide in the invitation.
I'm having trouble figuring out how to make this work smoothly with IOS only. It would be brilliant if I could send the invitee a link to appstore.apple.com/myapp?registrationKey=abcXYZ and have the key magically available to my app once it's installed, but I guess this is a lot to hope for?
The obvious way around this is to make the user manually enter their registration key on first launch, but this seems less reliable and (to my mind) adds friction to the UX.
Has anybody come up with something clever to get around this?
Here is what is flowing through my brain on how to solve this solution, please note, I have not vetted, psudeo-coded, coded, or applied this theory.
Since you will know who is being sent an invitation, save that data to your database with a relationship to the user sending and a unique id to the user being invited (email address if its in the contact's card). When new users sign up scan the database for invitations, if one is found present it to the user asking We're you referred by <existing user>? Once the new user selects their response continue through the registration process, updating the relationship table accordingly and applying any extra settings you need to for the referral.
This combines automatic referral tracking with referral codes for a basic, straight-forward, almost (but not quite) fool proof method to make sure referrals are linked to the right users.
As far as I can tell, the App Store provides an information firewall between an invitation and the installed app.
The closest workaround I've seen is the following:
email link sends you to your website
the website logs reference information in the URL and the IP address
the website instantly redirects you to the App Store (if iOS detected)
user installs the app
user loads the app
app contacts your website, IP addresses matched ... BINGO
Obviously not a secure method though.
There are many failure cases:
business networks commonly share IPs
home and mobile networks release and reuse IPs
The more is frequently used to resolve cases where its good enough to know that the user 'almost-certainly' was referred to download app by the email.
For example, it can be a good mechanism to prompt the user with a "who do you know" question in an app and limit the options based on the (IP+reference) data. If they pick the original poster, then maybe that's good enough, and then you can attach any other data that the inviter provided.
(Full disclosure, currently work at Branch)
The best solution to this is to fingerprint a user. This requires you to do the following steps:
For each user, using your own domain, generate a link for said user. So, right when they complete registration, generate their unique URL, that contains the invitation key.
For anyone clicking this link, they will redirect to Safari first. When they do, capture their IP address and iOS operating system version from the headers and user-agent.
Save this data on your server, and set window.location to your iTunes url.
If the user downloads and consequently opens, inside AppDelegate.m, send a message to your server with the IP address + major/minor/min version you collect upon app launch. If it matches with what you have on the server, you can now pass that invitation key back to the new user.
It's not perfect, and has the ability to misattribute. You could also use branch.io, where all of this is taken care of (link-generation, fingerprinting a user, attribution). Branch also drops a first party cookie and ties it with the device level ID, so attributions are much more accurate.
I am pretty new with iOS 5 and I am thinking in writing an app.
I would have a list of people inside the app who has it. Then I would invite them to an event.
I don't need any code right now I just wanted to know the concept behind this.
First, how an app can recognise who has my it installed, so it can show a list of people.
Second, after creating an event with a group of people how can I send an invitation to them.
Thanks
From a very general standpoint, what you need is a back-end server to interact with your app and store user/event info. You can either build your own or try to use a service like Parse.