NoisyTyper
首先得說一下WriteTyper的前身NoisyTyper,一開始我用的就是這個(gè)。
NoisyTyper是一款能夠讓你一遍打字一邊發(fā)出以前舊電影里老式打字機(jī)的聲音的Mac App,聲音相當(dāng)?shù)牟诲e(cuò)焕盟,十分耐聽拷沸。然而隨著時(shí)間的老去,系統(tǒng)的不斷更新剪勿,NoisyTyper開始漸漸的力不從心,不再適用于當(dāng)前系統(tǒng)方庭。于是乎厕吉,本君只好壓榨不多的時(shí)間,讓W(xué)riteTyper應(yīng)運(yùn)而生械念。
WriteTyper
NoisyTyper 是用OC寫的头朱,為了順應(yīng)時(shí)代的召喚,我決定龄减,參照NoisyTyper的代碼项钮,用Swift 2.0來寫WriteTyper。對(duì)于Mac桌面應(yīng)用希停,小生第一次寫表示怕怕烁巫,現(xiàn)在其實(shí)沒那么多的不同,只要將UIxxx的思維轉(zhuǎn)換成NSxxx就已經(jīng)一只腳踏入大門了宠能。
最后WriteTyper的成品如下圖亚隙,也就是說,我們要做的是一個(gè)menubar app而非window app违崇。
幾點(diǎn)筆記
申請(qǐng)權(quán)限:
// システム環(huán)境設(shè)定に設(shè)定変更を依頼する
func acquirePrivileges() -> Bool {
let accessEnabled = AXIsProcessTrustedWithOptions(
[kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String: true])
if !accessEnabled {
print("You need to enable the WriteTyper in the System Prefrences")
}
return accessEnabled
}
顯示/隱藏Dock Icon:
func toggleDockIcon(showIcon state: Bool) -> Bool {
var result: Bool
if state {
result = NSApp.setActivationPolicy(NSApplicationActivationPolicy.Regular)
}
else {
result = NSApp.setActivationPolicy(NSApplicationActivationPolicy.Accessory)
}
return result
}
全局鍵盤事件監(jiān)聽:
if isAcquirePrivileges {
NSEvent.addGlobalMonitorForEventsMatchingMask(
NSEventMask.KeyDownMask, handler: {(theEvent: NSEvent) in
let key = theEvent.keyCode
self.playSoundsByKey(key)
})
}
狀態(tài)欄上的pop view:
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(30)
let popover = NSPopover()
if let button = statusItem.button {
button.image = NSImage(named: "typewriter")
button.action = Selector("togglePopover:")
}
popover.contentViewController = SettingViewController(nibName: "SettingViewController", bundle: nil)
...
func showPopover(sender: AnyObject?) {
if let button = statusItem.button {
popover.showRelativeToRect(button.bounds, ofView: button, preferredEdge: .MinY)
}
}
func closePopover(sender: AnyObject?) {
popover.performClose(sender)
}
來自 stackoverflow 的搬運(yùn)
下面設(shè)置開機(jī)自啟的代碼來自stackoverflow阿弃,稍作修改诊霹,替換了過時(shí)的API:
func applicationIsInStartUpItems() -> Bool {
return (itemReferencesInLoginItems().existingReference != nil)
}
func itemReferencesInLoginItems() -> (existingReference: LSSharedFileListItemRef?, lastReference: LSSharedFileListItemRef?) {
if let appUrl : NSURL = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
let loginItemsRef = LSSharedFileListCreate(
nil,
kLSSharedFileListSessionLoginItems.takeRetainedValue(),
nil
).takeRetainedValue() as LSSharedFileListRef?
if loginItemsRef != nil {
let loginItems: NSArray = LSSharedFileListCopySnapshot(loginItemsRef, nil).takeRetainedValue() as NSArray
//print("There are \(loginItems.count) login items")
let lastItemRef: LSSharedFileListItemRef = loginItems.lastObject as! LSSharedFileListItemRef
for var i = 0; i < loginItems.count; ++i {
let currentItemRef: LSSharedFileListItemRef = loginItems.objectAtIndex(i) as! LSSharedFileListItemRef
if let resUrl = LSSharedFileListItemCopyResolvedURL(currentItemRef, 0, nil){
let urlRef: NSURL = resUrl.takeRetainedValue()
//print("URL Ref: \(urlRef.lastPathComponent!)")
if urlRef.isEqual(appUrl) {
return (currentItemRef, lastItemRef)
}
} else {
//print("Unknown login application")
}
}
//The application was not found in the startup list
return (nil, lastItemRef)
}
}
return (nil, nil)
}
func toggleLaunchAtStartup() {
let itemReferences = itemReferencesInLoginItems()
let shouldBeToggled = (itemReferences.existingReference == nil)
let loginItemsRef = LSSharedFileListCreate(
nil,
kLSSharedFileListSessionLoginItems.takeRetainedValue(),
nil
).takeRetainedValue() as LSSharedFileListRef?
if loginItemsRef != nil {
if shouldBeToggled {
if let appUrl : CFURLRef = NSURL.fileURLWithPath(NSBundle.mainBundle().bundlePath) {
LSSharedFileListInsertItemURL(
loginItemsRef,
itemReferences.lastReference,
nil,
nil,
appUrl,
nil,
nil
)
print("Application was added to login items")
}
} else {
if let itemRef = itemReferences.existingReference {
LSSharedFileListItemRemove(loginItemsRef,itemRef);
print("Application was removed from login items")
}
}
}
}
refs: http://stackoverflow.com/questions/26475008/swift-getting-a-mac-app-to-launch-on-startup
絲滑般的快感
本文就是伴著 WriteTyper 一字一字發(fā)出的老式打字機(jī)的聲音寫下的,全文行云流水渣淳,酣暢淋漓脾还,最后那感覺更不知與誰言說∪肜ⅲ總的來說鄙漏,上手體驗(yàn)還是不錯(cuò)的,對(duì)于經(jīng)常碼字的同志砂客,我相信泥张,這會(huì)是提高生產(chǎn)力的必備神器。
最后點(diǎn)評(píng)鞠值,每當(dāng)別人使用嘈雜不已的機(jī)械鍵盤渾然天成時(shí)媚创,你應(yīng)該默默的拿出本本,用打字機(jī)的聲音和他一干到底彤恶。
歡迎前往下載與Star钞钙。
官網(wǎng):https://urinx.github.io/app/writetyper
Github:https://github.com/Urinx/WriteTyper