Skip to content
Browse files

New post

  • Loading branch information...
wangshengjia committed Jul 2, 2016
1 parent be960ab commit a4f0ea020935401c8e2a54281e5baa370a526ed8
@@ -46,7 +46,7 @@ sass:
# Build Settings
permalink: pretty

markdown: redcarpet
# markdown: redcarpet
markdown_ext: markdown,mkdown,mkdn,mkd,md

@@ -0,0 +1,87 @@
layout: post
title: "Build your own Xcode 8 Source Editor Extension"
date: 2016-06-28
categories: Xcode
banner_image: ""
featured: false
comments: true

Since WWDC 2016, I was so excited about the announcement of the new Xcode source editor extension released in Xcode 8. Some of you may know I once wrote another [Xcode plugin called VWInstantRun](, an plugin made with some runtime hacks, a.k.a. old/unofficial way.

So naturally I'd love to port this plugin to the brand new Xcode source editor extension. I gave a try this weekend and I failed to implement `InstantRun` with the new approach. Basically there is two major limit to achieve it:


1. The only thing which expose to us from API is the text of current file inside a string buffer object. There is no way to access some UI relevant component at all. Which it's not possible to output the result directly into debug area as `VWInstantRun` do.
2. Since we suppose build thing inside an extension now, which is a sandbox. Which means there is no way to run build command in CLI during runtime.

Well, therefore I give it up. But I'm not saying the new Xcode extension is not worth to look at. In contrast, I think it's a very good beginning, by giving access of the most important part (the source editor) which allows to make [lots of useful features]( and meanwhile eliminating any potential privacy and safety threat.

## Build one

I'll try to give a simple tutorial here to show you how easy to build an Xcode extension yourself. Let's begin to do it by borrowing some ideas from AppCode, such as quickly deleting/duplicating selected lines.

#### I. Open Xcode 8.

(current version is beta 1)

Create a new macOS project and activate related scheme.

<p align="center"><img src="/media/new_mac_app.png" width="300"/></p>

Create a new target with Xcode source editor extension. (activate scheme proposed by Xcode)

<p align="center"><img src="/media/new_xcode_extension.png" width="300"/></p>

#### II. Configure.

Open `NSExtension` pair in `Info.plist` file, `XCSourceEditorCommandDefinitions` is an array contains a couple of `item`, an `item` represent a custom command. In each `item`, there are 3 pairs.

1. `XCSourceEditorCommandClassName`: The name of the class which you use to implement `XCSourceEditorCommand` protocol.
2. `XCSourceEditorCommandIdentifier`: The identifier you choose to identify the unique command
3. `XCSourceEditorCommandName`: The name of the command, which will show on Xcode menu.

Here we need to add two new commands: `delete_lines` & `duplicate_lines`.

<p align="center"><img src="/media/edit_plist.png" width="600"/></p>

#### III. Implementation.

Directly dive into `SourceEditorCommand`, implement protocol method:

public func perform(with invocation: XCSourceEditorCommandInvocation, completionHandler: (NSError?) -> Swift.Void)

Yes, there is only one method to implement. According to the description, this method will:

> Perform the action associated with the command using the information in an invocation. Xcode will pass the code a completion handler that it must invoke to finish performing the command, passing nil on success or an error on failure.
In other words, what you need to do is manipulating a `text buffer` based on the given information for different commands. You'll find all you need inside `invocation` instance. Once you finish, call completion handler, either pass `nil` or `error`.

Please checkout the details of the implementation directly from [code source on Github]( which is quite well documented.

#### IV. We are done ! 🎉🎉

Now run your project and test it with Xcode-beta. You'll find a one more gray color Xcode instance is created, that's the one you'll test and debug with.

<p align="center"><img src="/media/debug_xcode.png" width="300"/></p>

In your menu (the gray Xcode's menu), you'll find the commands you've added in `Info.plist`. Just try them.

<p align="center"><img src="/media/use_plugin.png" width="300"/></p>

You can also bind with hot key from Xcode settings.

## Where to go from here?

With Xcode 8 beta 1, there are still bunch of bugs (such as sometimes it just act as disabled), but this is definitely a good beginning. There is also a [WWDC video]( this year which dedicate this new feature, don't hesitate to check it out.

I've put the [project on Github](, if you have any questions or feedback, feel free to file an issue or ping me on Twitter by @wangshengjia.

Enjoy~ 🍻

@@ -0,0 +1,14 @@
layout: post
title: "iOS 10 brings notification to a whole new milestone"
date: 2016-06-28
categories: iOS
banner_image: ""
featured: false
comments: true

Not just for iOS, even for the entire mobile world, notification is definitely one of the most basic and important features. We have notification since iOS 3, but iOS 10 brings the notification to a whole new level. So even there are already a lot of people talked about it, I'd still love to give it a shot.

## New API
BIN +39.2 KB media/debug_xcode.png
Binary file not shown.
BIN +69.2 KB media/edit_plist.png
Binary file not shown.
BIN +72.4 KB media/new_mac_app.png
Binary file not shown.
Binary file not shown.
BIN +81.7 KB media/use_plugin.png
Binary file not shown.

0 comments on commit a4f0ea0

Please sign in to comment.
You can’t perform that action at this time.