Quickly add CloudKit-based chats to any iOS app
copyright 2015-16, Stand Alone, Inc. & Ben Gottlieb
Instructions for Use:
- Download the project and build the "Combined Framework" target
- This will generate a ConversationKit.framework
- Add ConversationKit.framework to your project, and make sure it's copied to your bundle at build time (this may require adding a Run Script step to your Build Phases in your target. See the Test Harness target in the project for an example)
- On the Apple Developer Portal, ensure that you've got iCloud support with CloudKit (check the "Include CloudKit support (requires Xcode 6)" checkbox)
- In your app's Capabilities pane in Xcode…
- Turn on "iCloud" and check the "CloudKit" checkbox (use default container is already selected)
- Turn on "Background Modes" and check the "Remote Notifications" checkbox
- In your app delegate add
- Add an
application(application,didReceiveRemoteNotification,fetchCompletionHandler)method, and call the same method on
- If you want the user to be able to reply to message notifications from outside the application, add an
application(application,handleActionWithIdentifier,forLocalNotification,withResponseInfo,completionHandler)method, and call the same method on
- Finally, call
ConversationKit.setupLocalSpeaker()with an identifier for the local user.
You're now set up. You can easily add a
ConversationView to a view controller, set its
conversation property, and you'll receive messages as they come in.
ConversationKit caches all data in a local CoreData database (stored in ~/Library/Caches/Conversations.db by default). It also caches all images (from avatars) in ~/Library/Caches/Images.
There is a ConversationKit object at the center of most of your interactions with ConversationKit. It's accessed via
feedbackLevelan enum controlling how much feedback you get when calling ConversationKit methods. Set to either
showNetworkActivityIndicatorBlocka closure that takes a single Bool, whether to show the Activity Indicator in the status bar. By default, it merely toggles it on and off, but youcan set a custom block to integrate with other Activity Indicator controls
cloudAvailableis CloudKit available (the user may be signed in or not)
configureNotifications(…)is called from
didFinishLaunching(…)to request permission to show notifications
application(application,didReceiveRemoteNotification,fetchCompletionHandler)called from the identically named Application Delegate method to process incoming notifications
fetchAccountIdentifier(…)takes a completion block which will be passed the user's CloudKit account identifier.
setup(containerName,completion)called before accessing most other ConversationKit methods. The containerName is optional, and the completion block will be called with a Bool indicating success
setupLocalSpeaker(identifier, completion)changes the identity of the local speaker. Called whenever the identity of the local speaker changes (new iCloud login, new GameCenter ID, etc). Calling with the existing identitfier does nothing. If necessary, will call
clearAllCachedDataWithCompletion(…)clears out the CoreData cache and all in-memory caches.
This object represents a user of the app, either the local user (
Speaker.localSpeaker) or whomever they're speaking to.
Speakers have the following properties:
nameThe user visible name that is shown to other speakers
identifiera unique string. Frequently their CloudKit account identifier (can be found using
ConversationKit.fetchAccountIdentifier()) or their GameCenter identifier
tagsan array of strings that can be used to search for users using the
isLocalSpeakera boolean indicating whether this is the local device user's speaker
avatarImagea UIImage representing the speaker and shown to other users
avatarImageLocalURLa file URL pointing to the user's avatar image
speakerRefa string representation of the user which can be stored and passed back to the
A few useful methods:
sendMessage(content, completion)send the user a message
There are also a few class methods and vars on the Speaker object:
allKnownSpeakersan array of Speakers representing all speakers the local speaker has either had a conversation with or found via a
maxImageSizea CGSize that all avatarImages will be capped to. Defaults to 100x100
Speakers are cached in the CoreData database as Speaker objects, and stored in CloudKit as ConversationKitSpeaker records.
A message represents a single message from one Speaker to another.
contenta string containing the message text
Speaker, who said it
Speaker, who it was said to
spokenAtan NSDate, when it was spoken
Conversationobject (see below) representing all
Messages between these two
Messages are cached in the CoreData database as Message objects, and stored in CloudKit as ConversationKitMessage records.
Conversation contains all
Messages between two
Speakerthat initiated the conversation
Speaker, the other side of the conversation
sortedMessagesa chronologically ordered list of
nonLocalSpeakerwhichever member of the conversation is NOT the localSpeaker
existingConversationWith(Speaker)looks up and returns an existing conversation between the local speaker and the passed in one
conversationWith(Soeaker)looks up existing and creates a new one if needed