0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

(Mac) Wi-Fiが切れたら自動で再接続するメニューバー常駐アプリケーション

Last updated at Posted at 2021-05-05

背景

うちの賃貸マンションはNuro光が無料で使えるのですが、手持ちのMacと相性が悪いのか、突然接続が切れることが度々あります。1日に1回以上の頻度で発生するため、さすがに対策が必要でした。

単にこちらをShell scriptあるいはApple Scriptで実装してもよいのですが、稼働している様子がわかるようにしたく、メニューバーに常駐するタイプのアプリケーションとして実装することにしました。

方法

基本的には、こちらのチュートリアルの通りに進めてメニューバー常駐アプリを作りました。

Swiftからshellコマンドを実行する方法としてこちらを使いました。

完成コード

AppDelegate.swift
import Cocoa


protocol CommandExecuting {
    func run(commandName: String, arguments: [String]) throws -> String
}

enum BashError: Error {
    case commandNotFound(name: String)
}


struct Bash: CommandExecuting {
    func run(commandName: String, arguments: [String] = []) throws -> String {
        return try run(resolve(commandName), with: arguments)
    }
    
    private func resolve(_ command: String) throws -> String {
        guard var bashCommand = try? run("/bin/bash" , with: ["-l", "-c", "which \(command)"]) else {
            throw BashError.commandNotFound(name: command)
        }
        bashCommand = bashCommand.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)
        return bashCommand
    }
    
    private func run(_ command: String, with arguments: [String] = []) throws -> String {
        let process = Process()
        process.launchPath = command
        process.arguments = arguments
        let outputPipe = Pipe()
        process.standardOutput = outputPipe
        process.launch()
        let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
        let output = String(decoding: outputData, as: UTF8.self)
        return output
    }
}


@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    
    
    @IBOutlet weak var menu: NSMenu!
    
    //メニューバーに表示されるアプリケーションを作成
    let statusItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.variableLength)
    
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // メニューバーに表示されるアプリ。今回は文字列で設定
        statusItem.title = "NURO"
        statusItem.highlightMode = true
        statusItem.menu = menu
        
        
        //アプリ終了ボタンを作成
        let quitItem = NSMenuItem()
        quitItem.title = "Quit Application"
        quitItem.action = #selector(AppDelegate.quit(_:))
        menu.addItem(quitItem)
        
        // WiFi再接続のループ開始
        startLoop()
    }
    
    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }
    
    @objc func quit(_ sender: Any) {
        NSApplication.shared.terminate(self)
    }
    
    
    func startLoop() {
        Timer.scheduledTimer(withTimeInterval: 3, repeats: true, block:{ (timer) in
            
            let bash: CommandExecuting = Bash()
            var result = ""
            do {
                try result = bash.run(commandName: "networksetup", arguments: ["-getinfo", "Wi-Fi"])
            }catch {
                print("failed to networksetup -getinfo")
                return
            }
            
            
            if (!result.contains("Subnet mask")) {
                do {
                    try result = bash.run(commandName: "networksetup", arguments:
                        ["-setairportnetwork", "en1", "HG8045-D94E-bg", "cuayh5ks"]
                    )
                } catch {
                    print("failed to networksetup -setairportnetwork")
                }
            }
            
            
        })
        
    }
    
}

ポイント

.entitlementsファイルで、App SandboxNOにする必要がある。

動作の様子

スクリーンショット 2021-05-05 20.35.25.jpg

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?