8
2

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 1 year has passed since last update.

ZOZOAdvent Calendar 2022

Day 22

使わなくなったiPhoneで自宅の回線速度を記録してみた

Last updated at Posted at 2022-12-21

この記事はZOZO Advent Calendar 2022Vol.1の22日目の記事です。

はじめに

こんにちは。株式会社ZOZOでiOSエンジニアをしている@_DS_Storeです。Qiitaに投稿するのは3年ぶりです。
今回はiPhoneを使って家の回線速度を記録しスプレッドシートに書き込むアプリを開発してみました。

image.png

きっかけ

今アパートに住んでいて備え付けの回線を使っているのですが、めちゃめちゃ回線が遅くなる時があり快適に仕事やゲームができないことがあります。そこで回線速度を記録して今後の生活に役立てようと思った次第です。

実装

回線速度の測定

回線速度を測るためにspeedchecker-sdk-iosというSDKを使用します。以下のようにXCFrameworkが提供されています。

image.png

直接ダウンロードしてプロジェクトに取り込んでもよかったのですがどうせならSPMに対応させたいと思ったので、フォークしてきてPackage.swiftを追加しました。PRも出しているのでマージされてほしい。

使用方法

SDKをimportしてInternetSpeedTestクラスのstartTest()を呼び出すと回線速度の測定が開始します。これをTimerで定期的に実行します。

SpeedTestManager.swift
import SpeedcheckerSDK
import CoreLocation

protocol SpeedTestDelegate {
    func progressDonwload(downloadMbps: Double)
    func progressUpload(uploadMbps: Double)
}

class SpeedTestManager: NSObject, CLLocationManagerDelegate {

    private var internetTest: InternetSpeedTest?
    private var locationManager = CLLocationManager()

    private var completion: ((_ download: Double, _ upload: Double) -> Void)?
    var delegate: SpeedTestDelegate? = nil

    override init() {
        super.init()
        Task {
            if CLLocationManager.locationServicesEnabled() {
                locationManager.delegate = self
                locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
                locationManager.requestWhenInUseAuthorization()
                locationManager.requestAlwaysAuthorization()
                locationManager.startUpdatingHeading()
            }
        }
    }

    // 計測開始、測定が終了したときに呼び出すcompletionを受け取る。
    func startTest(completion: @escaping (_ download: Double, _ upload: Double) -> Void) {
        internetTest = InternetSpeedTest(delegate: self)
        internetTest?.startTest() { error in
            if error != .ok {
                print(error)
            }
        }
        self.completion = completion
    }
}

extension SpeedTestManager: InternetSpeedTestDelegate {
    func internetTestFinish(result: SpeedTestResult) {
        if let completion {
            completion(result.downloadSpeed.mbps, result.uploadSpeed.mbps)
        }
    }

    func internetTestDownload(progress: Double, speed: SpeedTestSpeed) {
        delegate?.progressDonwload(downloadMbps: speed.mbps)
    }

    func internetTestUpload(progress: Double, speed: SpeedTestSpeed) {
        delegate?.progressUpload(uploadMbps: speed.mbps)
    }
}

SpeedTestViewConfig.swift
@MainActor
class SpeedTestViewConfig: ObservableObject {
    
    // Viewに表示する測定結果
    @Published var downloadMbps: Double = 0
    @Published var uploadMbps: Double = 0
    @Published var latestDate: Date = Date()

    let speedTestManager = SpeedTestManager()
    var timer: Timer?

    // タイマーで定期的に実行
    init() {
        self.timer = Timer.scheduledTimer(
            timeInterval: 60 * 5,
            target: self,
            selector: #selector(self.startTest),
            userInfo: nil,
            repeats: true
        )
        speedTestManager.delegate = self
    }

    // 計測開始
    @objc func startTest() {
        downloadMbps = 0
        uploadMbps = 0
        speedTestManager.startTest { downloadMbps, uploadMbps in
            Task.detached { @MainActor in
                self.latestDate = Date()
                self.downloadMbps = downloadMbps
                self.uploadMbps = uploadMbps
                try await self.post(
                    time: self.formattedDate(date: self.latestDate),
                    uploadSpeed: String(uploadMbps),
                    downloadSpeed: String(downloadMbps)
                )
            }
        }
    }

    private func post(time: String, uploadSpeed: String, downloadSpeed: String) async throws {
    // 結果をサーバに送信
    }
}

extension SpeedTestViewConfig: SpeedTestDelegate {
    func progressDonwload(downloadMbps: Double) {
        self.downloadMbps = downloadMbps
    }

    func progressUpload(uploadMbps: Double) {
        self.uploadMbps = uploadMbps
    }
}

結果の記録

測定結果はHTTPリクエストでGASで書かれたWebサーバに送られ、スプレッドシートに記録されます。

function doPost(e) {
  var jsonString = e.postData.getDataAsString();
  var data = JSON.parse(jsonString);

  var time = data.time;
  var uploadSpeed = data.uploadSpeed;
  var downloadSpeed = data.downloadSpeed;

  var ss = SpreadsheetApp.openById(SpreadsheetApp.getActiveSpreadsheet().getId());
  var sheet = ss.getSheetByName("シート1");

  sheet.appendRow([time, uploadSpeed, downloadSpeed])
}

おわりに

今回はiPhoneを使って家の回線速度を記録するアプリを開発しました。数日間記録してみてやっぱり夕方から夜の時間帯は遅いです。
全体の実装は以下のリポジトリにあるので気になる方はこちらから見てみてください。

8
2
1

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
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?