How to write an input method on iOS? This question has been answered a lot of people over。You can easily find a detailed tutorial by Google。but,On macOS write an input method is not so simple。
Ok,Strictly speaking,I mean use Swift to write a input method is difficult on macOS。The main reason is that no one has ever done this thing 。
Current data can be acquired,In addition to Apple's official API description (of no use),And the official demo (very detailed but outdated,But also written with OC。) Outside,Almost nothing。
Now I'm writing this article is to summarize,If you want to use Swift 3 to start to write a macOS input method,What you need to bypass pit。
Info.plist
For the input method for,Need to do some additional configuration in this document which,Most of the configuration you only need to compare apples to the official launch of the Demo - theymostThey are correct。
Where there is no explanation of that point,your Bundle identifier Need to follow a certain format to write - that,This field must contain inputmethod Keyword。
For example,,That name my input LogInputMac ,So I can not write with.logcg.LogInputMac ,In this case macOS not be able to recognize it as the input method (even into the /Repository/Input Methods/ Nor),You must inputmethod This keyword is added,And best not to put the final,It should be placed before the three dots (.) Within。For example, like me: with.logcg.inputmethod.LogInputMac 。
Other than that,For Swift,What you need to do a separate operation,If you like this APP will be compiled into /Repository/Input Methods/ ,So although macOS can recognize the input method,But does not actually have any effect - your IMKInputController It is not fully loaded。
This is because you can not find macOS IMKInputController class,to this end,We should InputMethodServerControllerClass and InputMethodServerDelegateClass To change the contents of the field $(PRODUCT_MODULE_NAME). Form of Prefix,That is,It should be written like this:
AppDelegate.swift
Because it works with an ordinary InputMethodKit different APP,We need to start the application initialization
IMKServer class,The first reaction of most people is to put it
applicationDidFinishLaunching(_ : ) Go execution,On the contrary,Since there is no main function Swift,We can declare it as a global variable without the need to give a global variable assignment statement,We write it in
applicationDidFinishLaunching in,At the same time you can also here to do some extra preparation.,For example, copy it thesaurus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import Cocoa import InputMethodKit let kConnectionName = "LogInputMac_2_Connection" var server = IMKServer() var candidatesWindow = IMKCandidates() @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { // Insert code here to initialize your application server = IMKServer(name: kConnectionName, bundleIdentifier: Bundle.main.bundleIdentifier) candidatesWindow = IMKCandidates(server: server, panelType: kIMKSingleRowSteppingCandidatePanel, styleType:kIMKMain) LogInputIMEngine.shared.cleanUp() } func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application } } |
Print(_:)
Because Swift is not OC use NSLog to output console messages,We all still like to use Print(_:) To achieve the printing terminal content - for the input method for,You can not debug a program。
If you perform your input directly with Xcode,There is no effect。Want to test input,We must put it /Repository/Input Methods/ And then load。In that case,Even if you use Xcode attach to an input method process,You will not get any output terminal。
This time you need to use NSLog ,It can easily input message is output to the console,So you can open a console,And then view the information process。
Debug
For the input method for,In osx it is a global thing,So it is hard to debug it be,Anyway,We can still make the development process as much as possible comfortable,First of all,You need to change the directory permissions input method:
1 |
sudo chmod -R 777 /Library/Input\ Methods |
This allows Xcode compiled directly into the directory,then,In the editing target in Xcode,
Build Settings > All > Build Locations > Per-configuration Build Products Path > Debug
The value corresponding to: /Library/Input Methods
So you can directly compiled,Add in System Preferences once,After compiling the facts can take effect,Back and forth without a restart or logout。
It is noteworthy that:Do not add breakpoints ......
Further reading
At last,Put hereThe only oneI could find the ChinesePresentation of the article InputMethodKit,We can refer to (unfortunately,I did not use this article,Because to find it when I have stepped on all the above pit)。
half year later,I restarted the project,And we found another one very useful article:IMK input method based on (a) the macOS - creating step
Other than that,I thought you might still unable to successfully control OC code to convert Swift project,So I put the Apple official correspondence "NumberInput_IMKit_Sample-NumberInput_0" the Swift project package upload,If desired, you canDownload Resources。
Original article written by LogStudio:R0uter's Blog » Swift uses InputMethodKit to write an input method
Reproduced Please keep the source and description link:https://www.logcg.com/archives/2078.html
The article is very useful! There may be some cooperation opportunities,How can I contact you?
Hello,I have an invention patent for the input scheme,I want to publish an input method app,I wonder if you are interested in cooperating。
your good friend,Sorry for the late reply,I was busy some time ago...
Cooperation can have,But I can only package、Part-time and other ways to work with you,Do not make a plan for dividends in the later stage of technology investment,If you can accept it,Let's talk further,See if it is a one-time payment. I develop and deliver according to your needs,Still pay for development according to working hours。
Of course,After the development is completed in the future,Maintenance work and development of new features, etc.,We can talk about it separately or later。
As for the developed code,Can be completely owned by you,If there is an algorithm related code that I use now,We can discuss separately (if possible,It can also be authorized to exchange, etc...
I don't know what went wrong,Appears every time you start[IMKServer _createConnection]: *Failed* to register NSConnection name=com.logcg.inputmethod_Connection错误,Have you encountered this problem,How to solve it
Check the NSConnection name in your code,That is IMKServer(name: kConnectionName, bundleIdentifier: Bundle.main.bundleIdentifier) The actual parameters in the and Info.plist InputMethodConnectionNameAre the settings in。
Thanks for this insightful post! I am also facing these stumbling blocks that you have mentioned as I am trying to write an input method using Swift. This is really sad that there are no input methods available which are written in Swift to learn from. I am having errors when compiling the example you have uploaded named FlyMac. It also doesn’t have the edits you have mentioned in this post like it doesn’t use $(PRODUCT_MODULE_NAME) in InputMethodServerControllerClass property. It’ll be a great help to me if you upload a working example.
Many thanks!
Hi there, in InputMethodServerControllerClass field you need insert your IMKInputController subclass name, in my project, NumberInputController.
The compiling error was that project somehow lost the AppIcon file, however, I have updated the project and now, in Swift 4.2.
https://www.logcg.com/wp-content/uploads/2016/10/FlyMac-1.zip
Very helpful dude! Thank you very much! I was missing the part about $(PRODUCT_MODULE_NAME) before the controller name!
;)
Hello there I am so happy I found your weblog, I really found you by accident, while I
was looking on Aol for something else, Anyhow I
am here now and wokuld just like to say thanks
a lot for a remarkable post and a all round exciting blog (I also love the theme/design),
I don’t have time to broiwse it all at the momernt but I
have saved it and also added your RSS feeds, so when I have time I will be back tto read more, Please do
keep up the superb job.
:) thanks! bro.
Sry cus I just found that I forgot to reply until now… XD
However, hope you enjoy.