UIActivityViewController Tutorial: Sharing Data [FREE]
source link: https://www.tuicool.com/articles/hit/2eEBvmI
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Update note : Owen L Brown updated this tutorial for Xcode 10.1, Swift 4.2, and iOS 12. Andy Pereira wrote the original.
A lot of developers want to be able to share their app data via email, Messages or AirDrop. Sharing is a convenient way for users to send data to each other or between devices. It may even net you some new customers!
Fortunately, since iOS 6, Apple has provided the handy, but much-overlooked, UIActivityViewController
class, which offers a clean interface for sharing and manipulating data inside your app.
You’ll learn everything you need to know to use this class in this UIActivityViewController
tutorial!
To set up sharing inside your app, you’ll have to configure some keys inside your app’s Info.plist
and handle a few system callbacks inside your app’s AppDelegate
. Once set up, iOS can open your app with the URL pointing to the data to import or export.
Ready for some book sharing fun? Read on.
Getting Started
First, download the materials for this tutorial at the top or bottom of this page using the Download Materials button. Build and run the starter project in Xcode and you’ll see the following:
Well, that’s no good; there are no books to share. Here’s how you can start sharing wonderful RW books with everyone.
UTIs and Your Plist
The first thing you need to do is set up your Info.plist to let iOS know your app can handle Book Tracker Documents .
To do this, you need to register your app as being able to handle certain Uniform Type Identifiers , or UTIs , exporting any UTIs that are not already known by the system.
In summary, UTIs are unique identifiers that represent documents. There are UTIs already built into iOS for handling common document types such as public.jpeg or public.html .
Defining Your UTIs
You’re going to register your app to handle documents with the com.raywenderlich.BookTracker.btkr UTI representing the description of a book.
You’ll give iOS information about the UTI, such as what file name extension it uses, what mime type it’s encoded as when sharing and, finally, the file’s icon.
So now it’s time to see it in action! Open Info.plist and add the following entries under the Information Property List key:
You can read up on what each of these values mean in Apple’s UTI guide , but here are the important things to note:
- The Document types entry defines what UTIs your app supports — in your case, the com.raywenderlich.BookTracker.btkr UTI, as an Owner/Editor.
- Document types is also where you set the names of the icons that iOS should use when displaying your file type. You’ll need to make sure you have an icon for each of the sizes listed in the plist.
- The Exported Type UTIs entry gives some information about com.raywenderlich.BookTracker.btkr , since it isn’t a public UTI. Here you define that your app can handle files ending in .btkr or files that have a mime type of application/booktracker .
Importing Your First Book
Believe it or not, by setting these keys, you have told iOS to start sending your app files that end with the .btkr extension.
You can test this out by emailing yourself a copy of the Swift Apprentice.btkr file from the Download Materials resource. Please make sure you unzip the file before emailing it to yourself. Otherwise, both the file extension UTI and mime type will be wrong.
You can tap on the attachment and it will prompt you to open the book in the Book Tracker app. Selecting Book Tracker will open the app. However, it won’t load the data from the sample file because you haven’t implemented the code for that yet.
Now that you’re a UTI wizard, it’s time for you to sprinkle some magic.
Note
: If you don’t see “Copy to Book Tracker” displayed in UIActivityViewController
after tapping the attached file in your email, you may need to edit the order of supported apps by scrolling to the end of the list, selecting More
, and moving “Copy to BookTracker” to the top of the list.
Importing App Data
Before you can handle opening data from the file, you’ll need some code that can work with the file that you have passed to it.
Add that code by opening Book.swift
, and replacing importData(from:)
with the following:
static func importData(from url: URL) { // 1 guard let data = try? Data(contentsOf: url), let book = try? JSONDecoder().decode(Book.self, from: data) else { return } // 2 BookManager.shared.add(book: book) // 3 try? FileManager.default.removeItem(at: url) }
Here’s a step-by-step explanation of the code above:
Book
Note : If you don’t delete these files as they come in, your app will continue to grow in size with no way for the user to clear the app’s data — except… by deleting your app!
Next, when an external app wants to send your app a file, iOS will invoke application(_:open:options:)
to allow your app to accept the file. Open AppDelegate.swift
and add the following code:
func application( _ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:] ) -> Bool { // 1 guard url.pathExtension == "btkr" else { return false } // 2 Book.importData(from: url) // 3 guard let navigationController = window?.rootViewController as? UINavigationController, let bookTableViewController = navigationController.viewControllers .first as? BooksTableViewController else { return true } // 4 bookTableViewController.tableView.reloadData() return true }
Here’s a step-by-step explanation of the code above:
- Verify the URL’s extension is btkr , since your app only supports files with that extension.
-
Use the
static
method onBook
you added above to import the data into your app. -
Verify the root view controller is an instance of a
UINavigationController
and that its first view controller is an instance ofBooksTableViewController
. -
Reload
BooksTableViewController
‘s table view to show the newly imported book, then returntrue
to inform iOS that your app successfully processed the provided book information.
Note
: The method still returns true
even if the view controller hierarchy was not set up correctly. This works because your app has, in fact, processed the provided book information in step two above.
Build and run your app. If all works well, you should be able to open the email attachment and see the book imported into your app as shown below.
Exporting App Data
So far in this UIActivityViewController
tutorial, you’ve added functionality to your app that handles importing data from other apps. However, what if you want to share your app’s data?
You’re in luck, as Apple has made exporting data nice and easy.
Your app will need code to handle exporting your favorite books. Open Book.swift
and replace the existing exportToURL()
definition with the following:
func exportToURL() -> URL? { // 1 guard let encoded = try? JSONEncoder().encode(self) else { return nil } // 2 let documents = FileManager.default.urls( for: .documentDirectory, in: .userDomainMask ).first guard let path = documents?.appendingPathComponent("/\(name).btkr") else { return nil } // 3 do { try encoded.write(to: path, options: .atomicWrite) return path } catch { print(error.localizedDescription) return nil } }
Here’s a step-by-step explanation of the code above:
-
Encode
Book
as JSON. - Verify that your app can access its Documents directory without error.
- Finally, save the data to your Documents directory and return the URL of the newly-created file.
Now that you can export Book
data to a file, you’re going to need an easy way to share that data. Open BookDetailViewController.swift
and replace the implementation of share(_:)
with the following:
@IBAction func share(_ sender: UIBarButtonItem) { // Get latest changes saveBook() // 1 guard let detailBook = detailBook, let url = detailBook.exportToURL() else { return } // 2 let activity = UIActivityViewController( activityItems: ["Check out this book! I like using Book Tracker.", url], applicationActivities: nil ) activity.popoverPresentationController?.barButtonItem = sender // 3 present(activity, animated: true, completion: nil) }
Here’s a step-by-step explanation of the code above:
-
Ferify that you have a detail book and that you can retrieve the URL from
exportToURL()
. -
Create an instance of
UIActivityViewController
and, foractivityItems
, pass in a message and the URL to your app’s data file. Depending on the activity the user selects from the activity menu, iOS uses the message you pass in to pre-populate its content. For example, if the user chooses to share the book via Email, the message you passed in will pre-populate the body of the email. Since not all activities have such capability, such as AirDrop, iOS may discard the message.UIActivityViewController
will do all of this heavy lifting for you and, since you defined all of the required information in your Info.plist , it’ll know just what to do with it. -
Present the
UIActivityViewController
to the user.
Build and run your app, open a book and try to share it. You’ll notice that you see a few options available to you as shown below:
UIActivityViewController
has been around since iOS6, but despite how useful it is, it’s often under-appreciated. Perhaps one of the best options is the ability to AirDrop. If you have two devices — or better yet, a friend with the Book Tracker app installed — you can test AirDropping books!
Where to Go From Here?
You can download the completed version of the project using the Download Materials button at the top or bottom of this tutorial.
Now that you know how iOS imports and exports app data, you’re ready to take this knowledge and start sharing your favorite books or any other data of your choice.
Here are some resources for further study:
- A video on the same topic from WWDC17: Extend Your App’s Presence With Sharing .
-
Another tutorial that leverages
UIActivityViewController
: Requesting App Ratings and Reviews Tutorial for iOS . -
If you’re interested to know how to make your app show up as an option within
UIActivityViewController
, you may want to watch iOS App Extensions video tutorial series .
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK