LoginSignup
2
3

More than 5 years have passed since last update.

Swift3のPlaygroundでnict.jpから時刻取得して表示する

Posted at

秒のレベルで正確な時刻をiPhoneで確認する場合、117に電話するくらいしか思いつかなかったので
nict.jpのAPIを叩いてJSONで値を貰い表示できれば良いんじゃない?と思い実験してみました。

既に似たアプリはあるわけですが、自分で実装するための勉強と将来的なアプリ化構想のネタです。
Time Signal (時報時計)

元ネタ

APIを叩く部分は、以前Qiitaに掲載したSwift3からAPIを叩いてJSONの値を取得するをベースにしています。

ハマったポイント

私の理解が浅いor誤りがある等で幾つか悩んだ点を列記します。
もし表記内で認識に誤りがあれば、ご指摘をお願いします。
* パースした結果の値”st”をStringで変数"jsonStr"に格納しようとして、型が違うと怒られました。
* URLにアクセスする時、非同期処理となってしまい肝心の結果が取得出来ませんでした。
* PlaygroundでURLにアクセスさせる条件が分からず、何をやったらできるの!?と悩みました。
* いつになっても実行処理が終わらない問題

ソース

下記コードはXcode Version 8.3.3 (8E3004b)で動作したことを確認しています。
iOS11対応等でUpdate済みの方は、動作が変わる可能性があります。ご了承下さい。

Playground
//: Playground - noun: a place where people can play

import UIKit
// ↓の2行が無いと、URLにアクセスできません。
import Foundation
import PlaygroundSupport


var getJson: NSDictionary!

// APIで取得する値をDouble型にする必要があり、宣言時に型を指定し初期値を代入しました。
var jsonStr : Double = 0
let urlStr = "https://ntp-a1.nict.go.jp/cgi-bin/json"

// いつになっても実行が終わらない問題に対応させる為の処理の一部です。
var currentPage = PlaygroundPage.current

if let url = URL(string: urlStr) {
    let req = NSMutableURLRequest(url: url)
    req.httpMethod = "GET"
    let task = URLSession.shared.dataTask(with: req as URLRequest, completionHandler: { (data, resp, err) in
        print(resp!.url!)
        print(NSString(data: data!, encoding: String.Encoding.utf8.rawValue) as Any)

        // 受け取ったdataをJSONパース、エラーならcatchへジャンプ
        do {
            // dataをJSONパースし、変数"getJson"に格納
            getJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary

            jsonStr = (getJson["st"] as? Double)!
            // UNIX時間をNSDate形式に変換
            let date = Date(timeIntervalSince1970:jsonStr)

            // NSDateFormatterを使用して任意のフォーマットの日本標準時間に変換
            let outputFormat = DateFormatter()
            outputFormat.locale = Locale(identifier: "ja_JP")
            outputFormat.dateFormat = "yyyy/MM/dd HH:mm:ss"
            print(outputFormat.string(from: date))

            // いつになっても実行が終わらない問題に対応させる為の処理の一部です。
            currentPage.finishExecution()

        } catch {
            print ("json error")
            return
        }
    })
    task.resume()
}else{
    print("Cannot get data from URL:\(urlStr)")
}

// 非同期処理で終了を明示的に指定する設定
PlaygroundPage.current.needsIndefiniteExecution = true
// Failed to obtain sandbox extensionというエラー対策(キャッシュが悪さしている模様)
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)


将来的に

できれば良いなというレベルではありますが
* NTPで時刻を取得時、iOSとの差を表示
* NTPで定期的に時刻を取得(or手動取得)
* NTPだけでなく、GPSやiOSが持つ時刻情報も表示
といった機能を実装したいところです。要は時刻情報の正らしさをユーザが判断できるようにしたいです。
最終的に117に電話しなくても、正しい時刻を取得できるようになれば良いですね。

参考URL

Special Thanks

@Ryuichirou

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