AVHider for macOS開發(fā)筆記

軟件介紹

AVHider (oh NO) FileHider是一款將你的文件夾或文件隱藏起來的效率軟件,適用于macOS X 10.10及以后的macOS版本迁匠。百度網(wǎng)盤下載地址,歡迎大家試用剩瓶,并提出改進(jìn)建議驹溃!有開發(fā)能力的朋友也可以去Github將項(xiàng)目fork后contribute您的code。

App logo

Specially thanks to unfamous Designer Joseph, who designed the exquisite logo for this Application!

軟件的使用也非常簡單延曙,基本可以實(shí)現(xiàn)文件/文件夾的可見/不可見一鍵切換豌鹤,錄了一個(gè)gif動(dòng)畫。

Demo

開發(fā)初衷

開發(fā)這款軟件的初衷將xxx.mp4/xxx.avi/xxx.mkv在白天藏起來枝缔,免得被其他人發(fā)現(xiàn)布疙。 在Apple store上發(fā)現(xiàn)了一款類似的軟件,售價(jià)163元愿卸,而且賣的不錯(cuò)灵临。作為一個(gè)工程師,我是不愿意掏這份冤枉錢的趴荸,因?yàn)槲矣X得這東西一天內(nèi)可以搞出來儒溉,于是就花了一晚上做出了功能類似的軟件FileHider(認(rèn)真臉)。

在Mac App Store定價(jià)為163元的Secret Folder

與Secret Folder不同的地方在于它的TableView中有兩列发钝,而我認(rèn)為顯示當(dāng)前文件可見/不可見的列跟右邊的NSSegmentedControl信息重復(fù)了睁搭,因此我就除去了該列。

還有一點(diǎn)不同是Secret Folder設(shè)置了Require Password這個(gè)選項(xiàng)笼平,這個(gè)我覺得可以不加园骆,因?yàn)槿绻粋€(gè)人在用戶不在的時(shí)候能夠進(jìn)入到系統(tǒng)中,那么user的密碼也是多余的寓调,F(xiàn)ileHider的目的是對(duì)有機(jī)會(huì)看到你電腦屏幕卻沒有機(jī)會(huì)操作你電腦的人隱藏文件锌唾。

起初我還想在用戶切換文件可見性的時(shí)候發(fā)送一個(gè)Notification,但是覺得過度設(shè)計(jì)了夺英,因?yàn)檫@些通知如果不手動(dòng)刪除晌涕,將會(huì)在通知中心保留下來,這顯然會(huì)增加別人知道有文件隱藏起來的可能性余黎。

開發(fā)過程

界面部分

界面部分完全模仿了Secret Folder的布局,是一個(gè)single-Page的應(yīng)用惧财,依然采用了StoryBoard構(gòu)造界面扭仁。

項(xiàng)目storyboard截圖

左右分為垂直的兩欄垮衷,使用了NSSplitView,并調(diào)整左右兩欄的大小比例乖坠,左邊顯示文件列表和對(duì)列表的增加/刪除按鈕;右邊是文件的詳細(xì)信息與文件隱藏/可見之間切換的NSSegmentedControl仰迁。對(duì)各個(gè)組件定好布局甸昏,確保在窗口resize后依然保持著相對(duì)較好的樣式。

TableView部分

文件列表是放到TableView中進(jìn)行顯示的徐许,它也是本應(yīng)用的核心部分筒扒。默認(rèn)的TableView Cell高度只有17px绊寻,每個(gè)Cell要塞進(jìn)去一個(gè)文件縮略圖icon和文件名悬秉,顯然過于小了,因此需要定制Cell村缸。在本項(xiàng)目中武氓,我將Cell設(shè)置為了30px梯皿,其中文件縮略圖為24 X 24 px,我覺得大小是比較合適的县恕。

TableView Cell

一個(gè)TableView要想成功顯示需要知道兩件事:1.顯示幾行忠烛、2.每行顯示什么。和其他應(yīng)用一樣冤议,驅(qū)動(dòng)這個(gè)TableView的是一個(gè)數(shù)組师坎,filesList : [URL]。請(qǐng)注意這里是一個(gè)URL的數(shù)組胯陋,文件路徑的URL都是定義為file://+文件路徑這種格式的。URL在Swift中有相當(dāng)多的方法寿弱,方便拿到文件名按灶、路徑名、根據(jù)完整路徑拿到對(duì)應(yīng)文件的縮略圖鸯旁、文件的detail信息等等。具體的使用可以參考官方API文檔艇挨。

數(shù)據(jù)持久化

對(duì)于本應(yīng)用,用戶對(duì)某個(gè)文件的操作并不是一次性隱藏就完事了的势就,它需要保留恢復(fù)為可見的權(quán)力脉漏,顯然讓用戶記住哪些文件被隱藏、甚至隱藏在哪個(gè)路徑下是很不現(xiàn)實(shí)的舅锄,因此需要數(shù)據(jù)持久化司忱,保證用戶下次打開應(yīng)用的時(shí)候可以知道哪些文件是有過隱藏歷史的。因?yàn)橛羞^前科的文件很可能需要二次隱藏坦仍。

數(shù)據(jù)持久化的選擇很多繁扎,最典型的有比較重的core data和比較輕量級(jí)的userDefaults。由于文件列表的路徑通常不會(huì)很長锻离,因此我選用了相對(duì)輕量級(jí)的userDefaults汽纠。

在使用userDefaults存儲(chǔ)前面提到的URL類型的filesList數(shù)組的時(shí)候,我發(fā)現(xiàn)會(huì)報(bào)一個(gè)錯(cuò)誤虱朵,Attempt to set a non-property-list object as an NSUserDefaults。 后面在網(wǎng)上發(fā)現(xiàn)了一些solution絮宁,主要的原因是NSUserDefaults只支持NSArray, NSDictionary, NSString, NSData, NSNumber, 和 NSDate的數(shù)據(jù)類型服协,對(duì)于URL這種類型,網(wǎng)上大多數(shù)的solution都是建議將數(shù)組編碼為NSData窘游,然后進(jìn)行存儲(chǔ)。我考慮到URL和String之間的互轉(zhuǎn)比較方便贪嫂,因此我將其轉(zhuǎn)換為了string類型的數(shù)組進(jìn)行存儲(chǔ)艾蓝。

// String -> URL
    override func viewDidLoad() {
        let defaults = UserDefaults.standard
        if let filesListFromUserDefaults = defaults.array(forKey: "filesPath"){
            var tmpFilePath : [String] = filesListFromUserDefaults as! [String]
            for str in tmpFilePath{
                self.filesList.append(URL(string: str)!)
            }
        }
    }
        
// URL -> String
    override func viewWillDisappear() {
        let defaults = UserDefaults.standard
        var array : [String] = []
        for url in filesList{
            array.append(url.absoluteString)
        }
        defaults.set(array, forKey: "filesPath")
    }

URL與String數(shù)組之間的互轉(zhuǎn)

轉(zhuǎn)換的時(shí)機(jī)很重要,這會(huì)提高應(yīng)用的性能亮靴。String->URL這個(gè)方向僅在應(yīng)用打開時(shí)敌厘,view加載完畢后進(jìn)行朽合;而URL->String這個(gè)方向是在應(yīng)用關(guān)閉后,view消失的時(shí)候觸發(fā)一次宪彩。

文件列表的增加

文件的增加目前是靠比較簡單的NSOpenPanel來實(shí)現(xiàn)的讲婚,顯然這很不Mac,后面需要做的是drag-and-drop活合,一種更為優(yōu)雅的solution物赶。

@IBAction func selectFile(_ sender: Any) {
        
        let openPanel = NSOpenPanel()
        
        openPanel.message = "Please select file to Hide"
        openPanel.canChooseDirectories = true
        //    openPanel.allowsMultipleSelection = true
        
        openPanel.beginSheetModal(for: view.window!, completionHandler: {(result) in
            if result == NSModalResponseOK{
                self.selectedFolder = openPanel.url!
            }
        })
    }

文件列表的刪除

文件列表的刪除依然是對(duì)上文提到的filesList進(jìn)行操作,通過tableviewDelegate中的tableViewSelectionDidChange方法得到需要?jiǎng)h除的元素index告嘲。需要注意的是奖地,需要增加判斷,確保當(dāng)前有元素被選中仰楚。(如果沒有元素被選中,index值會(huì)是-1缸血,這很可能引起應(yīng)用的崩潰)

無論是文件列表的增加還是刪除捎泻,都需要調(diào)用tableview.reloadData()方法對(duì)視圖進(jìn)行更新。

隱藏和非隱藏的實(shí)現(xiàn)

Unix系統(tǒng)中實(shí)現(xiàn)一個(gè)文件隱藏的方法很多笆豁,甚至可以給該文件進(jìn)行加密。我能想到的最簡單的方法是在原文件前面加一個(gè).煞赢,并用mv xxx.mp4 .xxx.mp4將該文件就地在原路徑下進(jìn)行隱藏哄孤。這也符合了本軟件的設(shè)計(jì)初衷,將文件從有機(jī)會(huì)從你電腦邊路過凝危,但卻沒有機(jī)會(huì)真正操作你電腦的人隱藏晨逝。

模擬console執(zhí)行命令,是通過Process()來完成的支鸡。這里有一些坑趁窃,不幸的被我全踩了。

第一個(gè)坑是普通文件和文件夾的URL是不同的醒陆,文件夾是以/結(jié)尾的,而普通文件則不是检碗,為了得到path和文件名码邻,我調(diào)用了String.components(separatedBy: “/“)方法,那么文件夾的文件名就存在了方法得到數(shù)組的倒數(shù)第二項(xiàng)中怕犁;而其他普通文件的文件名存在了數(shù)組的倒數(shù)第一項(xiàng)中。

第二個(gè)是當(dāng)用戶不是第一次打開應(yīng)用時(shí)戈轿,執(zhí)行mv的參數(shù)設(shè)置方式需要分四種情況討論阵子,這也是前面為了應(yīng)用的效率,不及時(shí)update fileList挖下的坑挠进。果然凡事都是有兩面性的~

致謝领突、結(jié)束語

首先感謝著名設(shè)計(jì)師Joseph給我提供的精美logo,感謝Secret Folder君旦,讓我有了靈感和動(dòng)力去做一個(gè)類似的軟件金砍。

周五有幸聆聽了公司CTO的演講,一個(gè)工程師的日常捞魁。我不禁聯(lián)想到了我自己离咐,我因?yàn)樵浖▋r(jià)過高,做過Syngery的替代品mouseSync昆著、Manico的替代品Manico-substitution术陶、Re Desktop的替代品HideDesktop,這也許就是我作為一個(gè)工程師的日常吧接谨。

Drag-and-drop是更為優(yōu)雅的文件與應(yīng)用的交互方式塘匣,我將于近期抽空集成進(jìn)應(yīng)用中,屆時(shí)再見扫夜!

參考

  1. Github
  2. stackoverflow
  3. FileManager Class Tutorial for macOS
  4. APPLE STORE:Secret Folder
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笤闯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子颗味,更是在濱河造成了極大的恐慌脱衙,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,029評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件退唠,死亡現(xiàn)場離奇詭異荤胁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)垢油,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門圆丹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人硝枉,你說我怎么就攤上這事倦微。” “怎么了责球?”我有些...
    開封第一講書人閱讀 157,570評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵拓劝,是天一觀的道長郑临。 經(jīng)常有香客問我,道長牧抵,這世上最難降的妖魔是什么侨把? 我笑而不...
    開封第一講書人閱讀 56,535評(píng)論 1 284
  • 正文 為了忘掉前任秋柄,我火速辦了婚禮蠢正,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘笨触。我一直安慰自己雹舀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評(píng)論 6 386
  • 文/花漫 我一把揭開白布虚吟。 她就那樣靜靜地躺著签财,像睡著了一般。 火紅的嫁衣襯著肌膚如雪邦鲫。 梳的紋絲不亂的頭發(fā)上神汹,一...
    開封第一講書人閱讀 49,850評(píng)論 1 290
  • 那天慎冤,我揣著相機(jī)與錄音沧卢,去河邊找鬼。 笑死但狭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼球及,長吁一口氣:“原來是場噩夢啊……” “哼几于!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起沿彭,我...
    開封第一講書人閱讀 37,747評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤喉刘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后睦裳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體廉邑,經(jīng)...
    沈念sama閱讀 44,207評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評(píng)論 2 327
  • 正文 我和宋清朗相戀三年肺素,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宇驾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片课舍。...
    茶點(diǎn)故事閱讀 38,683評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖捡需,靈堂內(nèi)的尸體忽然破棺而出筹淫,到底是詐尸還是另有隱情,我是刑警寧澤损姜,帶...
    沈念sama閱讀 34,342評(píng)論 4 330
  • 正文 年R本政府宣布摧阅,位于F島的核電站,受9級(jí)特大地震影響顾孽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜若厚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評(píng)論 3 315
  • 文/蒙蒙 一盹沈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乞封,春花似錦、人聲如沸锚贱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至墓卦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間睁本,已是汗流浹背忠怖。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枉疼,地道東北人问麸。 一個(gè)月前我還...
    沈念sama閱讀 46,401評(píng)論 2 360
  • 正文 我出身青樓严卖,卻偏偏與公主長得像布轿,于是被迫代替她去往敵國和親来颤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子稠肘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理项阴,服務(wù)發(fā)現(xiàn),斷路器环揽,智...
    卡卡羅2017閱讀 134,633評(píng)論 18 139
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫歉胶、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,066評(píng)論 4 62
  • 首先需要安裝mysql 然后新建數(shù)據(jù)庫 方法任意 我使用 Navicat字符集和排序順序如圖粥谬,別問我為什么imag...
    鏡kong閱讀 432評(píng)論 0 0
  • 今日文末蘇蘇送驚喜哦~ 怨氣沖天的女鬼有很多辫塌,咒怨里的伽椰子,午夜兇鈴里的貞子哟玷,而我們只愛過小倩一也。 你的腦海里只會(huì)...
    是年閱讀 361評(píng)論 0 1
  • 第78章回顧 “好,那么一言為定抑月∮吆”西涼大笑著,他的手好像只是輕輕一動(dòng)洁仗,那根竹劍就被深深地插入在了泥土的地上。 龍...
    陳瀛Neptune閱讀 439評(píng)論 21 12