Tải bản đầy đủ
Chapter 1. iMessage Stickers and Apps

Chapter 1. iMessage Stickers and Apps

Tải bản đầy đủ

1.1 Setting Up a Sticker Pack Application
Problem
You want to create a simple iMessage application that allows your users to send stick‐
ers to each other, without writing any code.

Solution
Follow these steps:
1. Open Xcode if it’s not already open.
2. Create a new project. In the new project dialog, choose Sticker Pack Application
and then click Next (Figure 1-1).

Figure 1-1. Creating a new sticker pack application for iMessage
3. Enter a product name for your project and then click Next (Figure 1-2).

2

|

Chapter 1: iMessage Stickers and Apps

Figure 1-2. Enter your sticker pack application’s product name here
4. You will then be asked to save the project somewhere. Choose an appropriate
location to save the project to finish this process.
5. You should now see your project opened in Xcode and then a file named Stick‐
ers.xcstickers. Click on this file and place your sticker images inside.
6. After you’ve completed these steps, test your application on the simulator and
then on devices as thoroughly as possible. Once you are happy, you need to code
sign and then release your app to the iMessage app store.

Discussion
With the opening up of iMessage as a platform where developers can build standalone apps, Apple has created a new type of store called iMessage App Store, where
applications that are compatible with iMessage will show up in the list and users can
purchase or download them without cost.
If you create a sticker pack app with no accompanying iOS app, your app shows up
only in the iMessage App Store. If you create an iOS app with an accompanying iMes‐
sage extension (stickers), your app shows up both in the iOS App Store (for the main
iOS app) and also in the iMessage App Store (for your iMessage extension).

1.1 Setting Up a Sticker Pack Application

|

3

Your stickers can be PDF, PNG, APNG (PNG with an alpha layer),
JPEG, or even (animated) GIF, but Apple recommends using PNG
files for the sake of quality. If you are desperate to create a sticker
app but have no images to test with, simply open Finder at /
System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/,
then open the ICNS files in that folder with Preview.app, export
those ICNS files into PNG files, and drag and drop them into your
Stickers.xcstickers file in Xcode. Then build and run your project on
the simulator.

See Also
Recipes 1.2 and 1.4

1.2 Adjusting Sticker Sizes
Problem
You have created a sticker pack application and you want to adjust the size of your
stickers in relation to how they appear on the screen.

Solution
Follow these steps in order to change the sticker sizes:
1. While in Xcode, click on the Stickers.xcstickers file that Xcode created and placed
in your project.
2. Open the Attributes inspector in Xcode using Command-Alt-4.
3. Locate the Sticker Pack section and then Sticker Size drop-down list in the
Attributes inspector and choose between Small, Medium, and Large (Figure 1-3).

4

|

Chapter 1: iMessage Stickers and Apps

Figure 1-3. Changing the sticker size in the Attributes inspector in Xcode

Discussion
After you ship your sticker applications to the iMessage store and a user downloads
them to her device, your stickers appear at a specific size both on the user’s device and
when sent to the recipient. This size is adjustable—not per sticker, but for the whole
sticker pack. All stickers must have the same size.
After you have changed this size, test your app thoroughly on the simulator and on
the device before shipping it to the iMessage app store. Ensure that there are no fuzzy
edges on your images and that curves look smooth.

See Also
Recipe 1.5

1.2 Adjusting Sticker Sizes

|

5

1.3 Building a Full-Fledged iMessage Application
Problem
You want to build a custom iMessage application where you have full control over the
presentation of your stickers and how the user interacts with them.

Solution
Create an iMessage application in Xcode by following these steps:
1. Open Xcode if it’s not already open.
2. Create a new project. In the template window choose iMessage Application and
then click Next (Figure 1-4).

Figure 1-4. Creating a full-fledged iMessage app
3. Enter the product name for your project and then click Next (Figure 1-5).
Choose Swift as the language, of course!

6

|

Chapter 1: iMessage Stickers and Apps

Figure 1-5. Enter your product name in this screen
4. You will be asked to save your project somewhere. Do so and then you should see
Xcode open up your project.

Discussion
Now that you have created your iMessage app, it’s time to learn a bit about what’s new
in the Messages framework for iOS 10 SDK. This framework contains many classes,
the most important of which are:
MSMessagesAppViewController

The main view controller of your extension. It gets displayed to users when they open
your iMessage application.
MSStickerBrowserViewController

A view controller that gets added to the app view controller and is responsible for
displaying your stickers to the user.
MSSticker

A class that encapsulates a single sticker. There is one MSSticker for each sticker in
your pack.

1.3 Building a Full-Fledged iMessage Application

|

7

MSStickerView

Every sticker instance in MSSticker has to be placed inside a view to be displayed to
the user in the browser view controller. MSStickerView is the class for that view.

For the sake of simplicity, in this recipe, I am going to hover over /System/Library/
CoreServices/CoreTypes.bundle/Contents/Resources/, grab the first three ICNS files out
of there, and export them, using Preview.app, into my desktop as PNG files with
alpha. Then I am going to drag and drop them into the Assets.xcassets file in my
Xcode project under the MessagesExtension section; not the main app’s Assets.xcassets
file.
When you build an iMessage application as we have just done, your app is then sepa‐
rated into two entry points:
• The iOS app entry point with your app delegate and the whole shebang
• The iMessage app extension entry point
This is unlike the sticker pack app that we talked about earlier in this chapter. Sticker
pack apps are iMessage apps but have no iOS apps attached to them. Therefore there
is no code to be written. In full-fledged iMessage apps, your app is divided into an
iOS app and an iMessage app, so you have two of some files, such as the Assets.xcas‐
sets file.
Even with custom sticker pack applications, you can build the apps in two different
ways:
• Using the existing Messages classes, such as MSStickerBrowserViewController,
which do the heavy lifting for you
• Using custom collection view controllers that will be attached to your main
MSMessagesAppViewController instance
This recipe explores the first method, because it is much easier to explain and carry
out. Once you have created the main structure of your application as described in this
recipe’s Solution, follow these steps to program the actual logic of the app:
1. Drag and drop your PNG stickers into your project’s structure, on their own and
not in an asset catalog. The reason is that we need to find them using their URLs,
so we need them to sit on the disk directly.
2. Create a new Cocoa Touch class in your project (Figure 1-6) that will be your
MSStickerBrowserViewController instance.

8

|

Chapter 1: iMessage Stickers and Apps

Figure 1-6. Creating a new Cocoa Touch class
3. Give your class the name of BrowserViewController (Figure 1-7), ensure it is of
type MSStickerBrowserViewController, and then click Next.

1.3 Building a Full-Fledged iMessage Application

|

9

Figure 1-7. Creating your browser view controller
4. Save your file inside your project in the new dialog that appears.
5. I have added three icons to my project: Burning, Alert, and Accounts. I grabbed
them from /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ as
described earlier. So it would be nice if my MSSticker class had an initializer
where I could just give it the name of the sticker, instead of the path of the image
to which it relates. I accomplish this by doing a search at runtime in the resources
for my app. I’ve created a MSStickerItem enumeration, whose three items match
the names of the images I dropped into my project. The extended initializer for
our MSSticker now accepts an instance of MSStickerItem and uses its name to
find the path of the image to apply to the sticker.
extension MSSticker{
enum MSStickerItem : String{
case Burning, Alert, Accounts
}
convenience init(item: MSStickerItem) throws{
try self.init(contentsOfFileURL:
Bundle.main.url(forResource: item.rawValue, withExtension: "png")!,
localizedDescription: "")
}

10

| Chapter 1: iMessage Stickers and Apps

}

6. In the newly created BrowserViewController, I create an array of my stickers:
class BrowserViewController: MSStickerBrowserViewController {
let stickers = [
try! MSSticker(item: .Burning),
try! MSSticker(item: .Alert),
try! MSSticker(item: .Accounts),
]
...

7. Your instance of MSStickerBrowserViewController has a property called
stickerBrowserView of type MSStickerBrowserView, which in turn has a prop‐
erty named dataSource of type MSStickerBrowserViewDataSource?. Your
browser view controller by default will become this data source, which means
that you need to implement all the non-optional methods of this protocol, such
as numberOfStickers(in:). So let’s do that now:
override func numberOfStickers(in
stickerBrowserView: MSStickerBrowserView) -> Int {
return stickers.count
}
override func stickerBrowserView(_ stickerBrowserView: MSStickerBrowserView,
stickerAt index: Int) -> MSSticker {
return stickers[index]
}

I’m explicitly unwrapping the optional value of the MSSticker
instance here because I know that those instances exist in my code.
If you are careful with optionals, like I am, in production code, try
to read the values first and then unwrap them only if they exist.

Our browser view controller is done, but how do we display it to the user? Remember
our MSMessagesAppViewController? Well, the answer is through that view controller.
In the viewDidLoad() function of the aforementioned view controller, load your
browser view controller and add it as a child view controller:

1.3 Building a Full-Fledged iMessage Application

|

11

override func viewDidLoad() {
super.viewDidLoad()
let controller = BrowserViewController(stickerSize: .regular)
controller.willMove(toParentViewController: self)
addChildViewController(controller)
if let vcView = controller.view{
view.addSubview(controller.view)
vcView.frame = view.bounds
vcView.translatesAutoresizingMaskIntoConstraints = false
vcView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
vcView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
vcView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
vcView.bottomAnchor.constraint(equalTo:
view.bottomAnchor).isActive = true
}
controller.didMove(toParentViewController: self)
}

Now press the Run button on Xcode to run your application on the simulator. You
will see a screen similar to Figure 1-8.

12

|

Chapter 1: iMessage Stickers and Apps