adding textexpander to your ios app - smile touch slides.pdf · textexpander requires 5.1 or later....
TRANSCRIPT
Adding TextExpander to Your iOS AppHave a great new feature in under an hour!
Greg Scown, co-founder, Smile
smilesoftware.com/sdkDelivered at altWWDC, June 13, 2013 at 11am in San Francisco, CA, USA
Good morning. I’m Greg Scown, co-founder of Smile, and I’m here today to show you how to add TextExpander to your iOS App.TextExpander offers a great way to add a high-value feature to your app in under an hour, and your users will be delighted by it.
smilesoftware.com/sdk
What is TextExpander?
TextExpander for Mac: May 2006
TextExpander touch: Sep 2009
SALT -> Short Abbreviations Lots of TextTx -> TextExpander@egs -> [email protected]
Adding TextExpander to your iOS App
TextExpander is designed to save-time typing.You set up short abbreviations which expand to larger snippets of text.TextExpander includes macros to support date and time formatting, date and time arithmetic, cursor positioning, and nesting one snippet within another.TextExpander also includes support for fill-in fields which include blanks, popups, and optional text sections so that you can easily customize what might normally be a common, boilerplate reply.
SDK
Free
Supported by 150+ apps: thank you!
Works with TextExpander touch app (US $4.99)
Easy to implement
Good citizen
smilesoftware.com/sdk Adding TextExpander to your iOS App
The TextExpander touch SDK is free of charge.Only a bullet point in your app description and a copyright / trademark acknowledgement is required. The latter can be on your website if that’s where you put such things, so long as it’s linked to from your app.Over 150 apps include TextExpander support, including some of the most popular notes and writing, task management, and social media apps. Examples include:! • Byword!! • Circus Ponies Notebook! • Drafts! • Elements! • OmniFocus!! • Things!! • Zendesk... and many more.We promote apps which include TextExpander touch support on our apps list page.Most useful with TextExpander touch app, though you can define a set of default snippets which work within your app even when TextExpander is not installed. Ideally, you’ll have a LinkShare link to the TextExpander touch app within your app when TextExpander is not installed.TextExpander is easy to implement. Basic functionality takes only about ten minutes, and you should be able to include fill-in support in under an hour.TextExpander is a good citizen. The SDK does not access the network, and it presents no UI within your app.
SDK Basics
Requires iOS 5.1 or later
TextExpander.framework
Requires CoreGraphics, CoreText, AudioToolbox
Works with UITextView, UITextField, UISearchBar, and UIWebView
Supports attributed text
smilesoftware.com/sdk Adding TextExpander to your iOS App
TextExpander requires 5.1 or later. Likely, it works fine on iOS 5.0 as well, but we’ve not tested that so we don’t claim support.TextExpander is packaged as a fat framework with armv7, armv7s, and i386 for the simulator.In addition to UIKit and Foundation, TextExpander requires CoreGraphics, CoreText, and the AudioToolbox.TextExpander works with the standard UIKit text classes and includes support for attributed text. This requires TextExpander touch 2.0 or later, which was released on May 21st.
Implementation“Middleman” delegate
YourTextControllerClass
smilesoftware.com/sdk Adding TextExpander to your iOS App
SMTEDelegateController
YourTextClassDelegate
delegate
nextDelegate
Basic implementation is fairly simple.You create an SMTEDelegateController object. A single instance can be shared among multiple text objects in your app, or you can create multiple instances.You set the delegate of your text object controller to your SMTEDelegateController object.If you didn’t have a delegate before, you’re done.If you did have a delegate before, you set the nextDelegate of your SMTEDelegateController object to your text object’s delegate.Essentially, you place the SMTEDelegateController object in the middle of your text object and its delegate.
ImplementationThe view from Xcode
smilesoftware.com/sdk Adding TextExpander to your iOS App
Import the SMTEDelegateController header.Create a member for your text view.Create a member for the SMTEDelegateController object. We recommend calling it textExpander as in this example.
ImplementationThe view from Xcode
smilesoftware.com/sdk Adding TextExpander to your iOS App
Here is the code version of the diagram we saw earlier.When the view is loaded, we create an instance of the SMTEDelegateController.We set the delegate of our text view to the newly-created SMTEDelegateController object.We set the nextDelegate of our SMTEDelegateController object to the text view’s delegate.
Expansion MechanicsPerformed in shouldChangeTextInRange
smilesoftware.com/sdk Adding TextExpander to your iOS App
Content is copied and modi!ed with expanded text
Sets isAttemptingToExpandText
Calls nextDelegate’s shouldChangeTextInRange
On YES, calls replaceCharactersInRange
Returns NO from shouldChangeTextInRange
Here is how the expansion works under the hood.The SMTEDelegateController is a delegate of your UITextView.Its textView:shouldChangeTextInRange:replacementText: method is called when text is changedWhen an abbreviation is detected, a copy of the content is made and modified with the snippet content.The isAttemptingToExpandText property is set, then nextDelegate’s textView:shouldChangeTextInRange:replacementText: method is called with modified parameters.You can check isAttemptingToExpandText in your nextDelegate method if you need to detect expansion.Your nextDelegate returns NO to cancel or YES to proceed.If YES, the content replacement is performed and TextExpander returns NO from the original delegate method call so that iOS drops the final character of the abbreviation rather than inserting it into the text view.And that is the essence of the wonder the TextExpander performs.
Fill-in Implementationx-callback-url
Your App Your App
Fill-in snippet triggered, launches
TextExpander
Fill-in snippet completed, back to your app via URL
smilesoftware.com/sdk Adding TextExpander to your iOS App
The logic and presentation for fill-ins is done within the TextExpander touch app.This allows for the TextExpander touch SDK to remain small (~800K of payload).When a fill-in snippet is triggered, TextExpander is launched via its URL handler.When a fill-in snippet is completed, your app is launched via its URL handler.
Fill-in ImplementationURL handling
smilesoftware.com/sdk Adding TextExpander to your iOS App
Add URL scheme to your app, or plan to use existing one
Your App Implement or update open:URL: in your app delegate
If your app does not have a URL scheme, you’ll need to add one. That’s done via your app’s target under the Info tab under “URL Types”. You can name your URL scheme whatever you wish.If your app does have a URL scheme, you can use that, as TextExpander will be able to distinguish its callbacks from your app’s callbacks. If you go this route, please read the part in the readme which explains how TextExpander constructs the callback URL to ensure that does not conflict with your app.Either way, please make note of your URL scheme name for later steps.
Fill-in ImplementationView Controller setup
self.textExpander.fillCompletionScheme = @"x-te-yourapp";self.textExpander.fillForAppName = @"Your App";self.textExpander.fillDelegate = self;
In your view controller’s viewDidLoad method, add:
smilesoftware.com/sdk Adding TextExpander to your iOS App
In your view controller’s viewDidLoad method, you’ll need to set the fill-in related parameters of your SMTEDelegateController object.Set fillCompletionScheme to the name of your URL scheme you noted earlier.Set the fillForAppName to your app’s name.Set the fillDelegate to whichever object you use to implement the SMTEFillDelegate protocol, typically the view controller.When TextExpander completes a fill-in and returns to your app, application:openURL:sourceApplication:annotation: will get called.We make it easy to differentiate between a TextExpander fill-in URL call and other URLs that might be calling your app.
Fill-in ImplementationSMTEFillDelegate
- (NSString*)identifierForTextArea:(id)uiTextObject
Returns unique identi!er for view object
- (BOOL)prepareForFillSwitch:(NSString*)textIdentifier
Called before switching to TextExpanderOpportunity to save state
- (id)makeIdentifiedTextObjectFirstResponder:(NSString*)textIdentifier! ! ! ! fillWasCanceled: (BOOL)userCanceledFill! ! ! ! cursorPosition: (NSInteger*)ioInsertionPointLocation;
Restore active typing location and cursor positionReturn view object or nil to cancel
smilesoftware.com/sdk Adding TextExpander to your iOS App
The SMTEFillDelegate protocol allows TextExpander to uniquely identify text objects, allows your app to record state when a fill-in is triggered, and asks your app to restore your text object as the first responder with its cursor positioned properly after a fill-in.There is greater detail in the SMTEDelegateController header.If your app is still loaded upon return from the fill-in, typically no work is required in makeIdentifiedTextObjectFirstResponder:fillWasCancelled:cursorPosition:You’ll want to pay particular attention if your app uses TextExpander for a UIWebView.
Special Cases
UITextInput custom view
Can’t return after !ll-in
Con"icting custom JavaScript
smilesoftware.com/sdk Adding TextExpander to your iOS App
So far, we’ve learned of three special case areas which are worth noting.If you have a custom view which implements the UITextInput protocol but isn’t a UITextView, it probably doesn’t implement the UITextViewDelegate. Your best bet in that case is to mimic the UITextViewDelegate if possible. If not, let us know and we’ll see if we can figure something out with you.It’s possible your app can’t return to the input view after a fill-in if it gets unloaded. You should gracefully note that to the user. You should also let us know, as perhaps we should be doing more to settle this case. We’d prefer to avoid moving the fill-in UI into the framework. Maybe you have an alternate suggestion.We handle UIWebViews by injecting custom JavaScript. We took care to name things to avoid conflict. If you find you’re unable to get expansion to work in a UIWebView, maybe you’re wiping out our custom JavaScript. Feel free to let us know if you have trouble and we’ll see what we can do to help.
SDK home: smilesoftware.com/sdk
GitHub: SmileSoftware/TextExpanderTouchSDK
App List: smilesoftware.com/apps
Support: [email protected]
Google Group: tetouch-sdk
x-callback-url info: x-callback-url.com
SDKResources
Here are TextExpander SDK resources.There is sample code in the SDK repository.There is an iPhone Simulator app package in the SDK.There are two Clarify It tutorials linked from the SDK home -- one on the basics and another on fill-ins.Please join the Google group, as that’s how we send notices of SDK updates.Mail us if you have questions.Special thanks to Bob Cantoni for his work on the tutorials and to Brian Bucknam for his tireless work on TextExpander.Brian and I will be around after the presentation.Thank you so much for attending, and we hope you’ll adopt TextExpander in your app!