0

iPhoneで動くタイマーアプリを作りました。iPhoneとWatchをコントロールできたらいいのに

プロジェクトのスクリーンショット

iPhone でのコントロール (再生、停止、再起動) は正常に機能し、私のメーターは Watch に表示されます。

ストップでの時計はうまく機能します。スタートに対しては機能しません。メーターはiPhoneまたは時計の電源を入れません。

工事も再開。

iPhone 上の My Label は、情報が Watch からのものである場合、変更に非常に時間がかかりますが、iPhone Watch に向かう逆の方向ではうまく機能します。

この問題に気付きましたか、これは WatchConnectivity に関連する問題です

ご協力いただきありがとうございます

以下は私のコードです:

ViewController.swift

import UIKit
import WatchConnectivity

class ViewController: UIViewController, WCSessionDelegate {

@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var watchLabel: UILabel!

var session: WCSession!
var timerCount = 0
var timerRunning = false
var timer = NSTimer()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    if (WCSession.isSupported()) {
        let session = WCSession.defaultSession()
        session.delegate = self
        session.activateSession()

        if session.paired != true {
            print("Apple Watch is not paired")
        }

        if session.watchAppInstalled != true {
            print("WatchKit app is not installed")
        }
    } else {
        print("WatchConnectivity is not supported on this device")
    }

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}    


@IBAction func startButton(sender: UIButton) {
    startPlay()
}

@IBAction func stopButton(sender: UIButton) {
    stopPlay()
}


@IBAction func restartButton(sender: UIButton) {
   restartPlay()
}

//Receive messages from watch
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
    var replyValues = Dictionary<String, AnyObject>()

    //let viewController = self.window!.rootViewController as! ViewController      
    switch message["command"] as! String {
    case "start" :
        startPlay()
        replyValues["status"] = "Playing"
    case "stop" :
        stopPlay()
        replyValues["status"] = "Stopped"
    case "restart" :
        restartPlay()
        replyValues["status"] = "Stopped"
    default:
        break
    }
    replyHandler(replyValues)
}

//Counter Timer
func counting(timer:NSTimer) {
    self.timerCount++
    self.timerLabel.text = String(timerCount)

    let requestValues = ["timer" : String(timerCount)]
    let session = WCSession.defaultSession()
    session.sendMessage(requestValues, replyHandler: nil, errorHandler: { error in print("error: \(error)")})
}

//Fonction Play
func startPlay() {
    if timerRunning == false {
        self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("counting:"), userInfo: nil, repeats: true)
        self.timerRunning = true
        self.watchLabel.text = "START"
    }
}

//Fonction Stop
func stopPlay() {
    if timerRunning == true {
        self.timer.invalidate()
        self.timerRunning = false
        self.watchLabel.text = "STOP"
    }
}

//Fonction Restart
func restartPlay() {
    self.timerCount = 0
    self.timerLabel.text = "0";

    let requestValues = ["timer" : "0"]
    let session = WCSession.defaultSession()
    session.sendMessage(requestValues, replyHandler: nil, errorHandler: { error in print("error: \(error)")})
}
}

InterfaceController.swift

import WatchKit
import Foundation
import WatchConnectivity


class InterfaceController: WKInterfaceController, WCSessionDelegate {

@IBOutlet var watchLabel: WKInterfaceLabel!
@IBOutlet var statusLabel: WKInterfaceLabel!

//Receiving message from iphone
func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) {
    self.watchLabel.setText(message["timer"]! as? String)
    // self.statusLabel.setText(message["command"]! as? String)
}


override func awakeWithContext(context: AnyObject?) {
    super.awakeWithContext(context)
    // Configure interface objects here.
}

override func willActivate() {
    // This method is called when watch view controller is about to be visible to user
    super.willActivate()
    if (WCSession.isSupported()) {
        let session = WCSession.defaultSession()
        session.delegate = self
        session.activateSession()
    }
}

override func didDeactivate() {
    // This method is called when watch view controller is no longer visible
    super.didDeactivate()
}


@IBAction func startButtonWatch() {
    if WCSession.defaultSession().reachable == true {
        let requestValues = ["command" : "start"]
        let session = WCSession.defaultSession()
        session.sendMessage(requestValues, replyHandler: { reply in
            self.statusLabel.setText(reply["status"] as? String)
            }, errorHandler: { error in
                print("error: \(error)")
        })

    }

}


@IBAction func stopButtonWatch() {
    if WCSession.defaultSession().reachable == true {
        let requestValues = ["command" : "stop"]
        let session = WCSession.defaultSession()
        session.sendMessage(requestValues, replyHandler: { reply in
            self.statusLabel.setText(reply["status"] as? String)
            }, errorHandler: { error in
                print("error: \(error)")
        })

    }
}

@IBAction func restartButtonWatch() {
    if WCSession.defaultSession().reachable == true {
        let requestValues = ["command" : "restart"]
        let session = WCSession.defaultSession()
        session.sendMessage(requestValues, replyHandler: { reply in
            self.statusLabel.setText(reply["status"] as? String)
            }, errorHandler: { error in
                print("error: \(error)")
        })

    }

}

}
4

2 に答える 2

0

この機能的で最適化されたコード:

//Fonction Play
func startPlay() {
    if timerRunning == false {
        self.mytimer = NSTimer(timeInterval: 1, target: self, selector: "counting:", userInfo: nil, repeats: true)
        NSRunLoop.mainRunLoop().addTimer(self.mytimer, forMode: NSRunLoopCommonModes)
        timerRunning = true
        dispatch_async(dispatch_get_main_queue()) {
            self.watchLabel.text = "PLAYING"
        }
    }
}
于 2015-10-23T08:04:34.540 に答える
0


これを使用する必要があります:

   func startPlay() {
    if timerRunning == false {
        //self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("counting:"), userInfo: nil, repeats: true)
        self.timer = NSTimer(timeInterval: 1, target: self, selector: "counting:", userInfo: nil, repeats: true)
        NSRunLoop.mainRunLoop().addTimer(self.timer, forMode: NSRunLoopCommonModes)
        self.timerRunning = true
        self.watchLabel.text = "Start"
    }
}


NSRunLoop を明示的に使用する必要がある理由を説明できません。データ転送を使用してアプリを開発するときに、同じタイマーの問題が発生しました。クエリ「nstimer run loop」またはここでGoogleで見つけることができるいくつかの答え。
そして、私はこれを再起動に使用することを好みます:

    func restartPlay() {
    self.timerCount = 0
    self.timerLabel.text = "0";
    stopPlay()
    startPlay()
    self.watchLabel.text = "Restarted"
}


乾杯。

于 2015-10-22T13:50:21.703 に答える