如何防止自定义Swift应用程序跳回主屏幕?

时间:2018-03-16 11:42:34

标签: ios swift arduino homescreen

知识渊博的人,

我正在Swift中编写一个应用来控制我的车库门。该应用程序有4个按钮,用户可以从中选择。用户按下按钮后,只要连接到我的家庭局域网,该应用程序就会通过传递JSON消息与Arduino(也在局域网上)进行通信。然后Arduino激活一个继电器来打开/关闭门。

最初将应用程序部署到我的iPhone后,它打开正常。但是,如果我几天不使用该应用程序,然后尝试再次打开它,而不是使用4个按钮显示屏幕,而是跳回主屏幕。此外,如果我双击主页按钮,我会看到正确的应用程序窗口,但如果尝试将其带到前台,我会被迫再次返回主屏幕。

我已将我的代码包含在下面,我希望有人可以指出我做错了什么?由于需要几天才能显示问题,我还没有能够进行彻底的调试。所以,我很难过。感谢您的帮助。

import UIKit

let INITIAL_STATE : Int = 0
var MADE_INITIAL_CONTACT : Int = 0
//let SETTINGS_FILENAME = "userSettings.plist"


class ViewController: UIViewController {

    @IBOutlet weak var leftOpenImage: UIImageView!
    @IBOutlet weak var leftClosedImage: UIImageView!
    @IBOutlet weak var rightOpenImage: UIImageView!
    @IBOutlet weak var rightClosedImage: UIImageView!

    var leftOpenLED = -1
    var leftClosedLED = -1
    var rightOpenLED = -1
    var rightClosedLED = -1
    var arduinoURL = "http://192.168.1.74"

    override func viewDidLoad() {
        super.viewDidLoad()

        // These routines below are all identical. They
        // make the UIImageView touch actionable. I found
        // a StackOverflow post that described how to do this for 
        // this version of Swift...God I hate Apple...and Swift


        let tgrLeftOpen = UITapGestureRecognizer(target: self, action: #selector(leftOpenImageTapped(tgrLeftOpen:)))
        leftOpenImage.isUserInteractionEnabled = true
        leftOpenImage.addGestureRecognizer(tgrLeftOpen)


        let tgrLeftClosed = UITapGestureRecognizer(target: self, action: #selector(leftClosedImageTapped(tgrLeftClosed:)))
        leftClosedImage.isUserInteractionEnabled = true
        leftClosedImage.addGestureRecognizer(tgrLeftClosed)


        let tgrRightOpen = UITapGestureRecognizer(target: self, action: #selector(rightOpenImageTapped(tgrRightOpen:)))
        rightOpenImage.isUserInteractionEnabled = true
        rightOpenImage.addGestureRecognizer(tgrRightOpen)


        let tgrRightClosed = UITapGestureRecognizer(target: self, action: #selector(rightClosedImageTapped(tgrRightClosed:)))
        rightClosedImage.isUserInteractionEnabled = true
        rightClosedImage.addGestureRecognizer(tgrRightClosed)


        // get initial door states from Arduino

        /*
        if (MADE_INITIAL_CONTACT == 0) {
            performRestCall()
            MADE_INITIAL_CONTACT = 1

            print("STILL IN HERE")
        }
        */

        performRestCall()
    }


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


    func leftOpenImageTapped(tgrLeftOpen: UITapGestureRecognizer) {
        // if left door closed, open it
        if (leftOpenLED == 0 && leftClosedLED == 1) {
            // change which images are highlighted
            leftOpenImage.image = UIImage(named: "open-25%")
            leftClosedImage.image = UIImage(named: "closed")
            print("You tapped the left door open button!")

            // update door state
            leftOpenLED = 1
            leftClosedLED = 0

            print("LeftOpenLED is now ")
            print(leftOpenLED)
            print("LeftClosedLED is now ")
            print(leftClosedLED)

            // create new JSON message to send to Arduino
            CreateJSONMessage()
        }
    }


    func leftClosedImageTapped(tgrLeftClosed: UITapGestureRecognizer) {
        // if left door open, close it
        if (leftOpenLED == 1 && leftClosedLED == 0) {
            // change which images are highlighted
            leftClosedImage.image = UIImage(named: "closed-25%")
            leftOpenImage.image = UIImage(named: "open")
            print("You tapped the left door closed button!")

            // update door state
            leftOpenLED = 0
            leftClosedLED = 1

            print("LeftOpenLED is now ")
            print(leftOpenLED)
            print("LeftClosedLED is now ")
            print(leftClosedLED)

            // create new JSON message to send to Arduino
            CreateJSONMessage()
        }
    }


    func rightOpenImageTapped(tgrRightOpen: UITapGestureRecognizer) {
        // if right door closed, open it
        if (rightOpenLED == 0 && rightClosedLED == 1) {
            // change which images are highlighted
            rightOpenImage.image = UIImage(named: "open-25%")
            rightClosedImage.image = UIImage(named: "closed")
            print("You tapped the right door open button!")

            // update door state
            rightOpenLED = 1
            rightClosedLED = 0

            print("rightOpenLED is now ")
            print(rightOpenLED)
            print("rightClosedLED is now ")
            print(rightClosedLED)

            // create new JSON message to send to Arduino
            CreateJSONMessage()
        }
    }


    func rightClosedImageTapped(tgrRightClosed: UITapGestureRecognizer) {
        // if right door open, close it
        if (rightOpenLED == 1 && rightClosedLED == 0) {
            // change which images are highlighted
            rightClosedImage.image = UIImage(named: "closed-25%")
            rightOpenImage.image = UIImage(named: "open")
            print("You tapped the right door closed button!")

            // update door state
            rightOpenLED = 0
            rightClosedLED = 1

            print("rightOpenLED is now ")
            print(rightOpenLED)
            print("rightClosedLED is now ")
            print(rightClosedLED)

            // create new JSON message to send to Arduino
            CreateJSONMessage()
        }
    }


    /*  performRestCall() simply takes the URL you provided to talk to the Arduino and sets up a background HTTP request using an Operation Queue. We utilize Swift closures to handle the results of the background web request.

     The code receives the results and calls handleResultsOfWebCall(_:) on the main thread which parses and displays the results.
     */
    func performRestCall() {

        let url = URL(string: arduinoURL)
        var request = URLRequest(url: url! as URL)
        request.httpMethod = "GET"
        request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")

        let session = URLSession.shared
        let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in

            guard error == nil else {
                print("Guard error")
                print(error!)
                return
            }
            guard let data = data else {
                print("Data is empty")
                return
            }

            //let json = try! JSONSerialization.jsonObject(with: data, options: [])
            //print(json)
            self.handleResultsOfWebCall(theData : data)
        })

        task.resume()
    }



    /* This parses the JSON information. This method checks to see if any data was returned, and then uses the built-in NSJSONSerialization handler to get the results into a NSDictionary object.

     */
    func handleResultsOfWebCall(theData : Data) {
        do {
            let jsonResults = try JSONSerialization.jsonObject(with: theData as Data, options:.allowFragments) as! [String:Any]

            self.leftOpenLED = jsonResults["leftOpenLED"] as! Int
            self.leftClosedLED = jsonResults["leftClosedLED"] as! Int
            self.rightOpenLED = jsonResults["rightOpenLED"] as! Int
            self.rightClosedLED = jsonResults["rightClosedLED"] as! Int

            //print("leftOpenLED = \(leftOpenLED)")
            //print("leftClosedLED = \(leftClosedLED)")
            //print("rightOpenLED = \(rightOpenLED)")
            //print("rightClosedLED = \(rightClosedLED)")

            if (leftOpenLED == 1 && leftClosedLED == 0) {
                // change which images are highlighted
                leftOpenImage.image = UIImage(named: "open-25%")
                leftClosedImage.image = UIImage(named: "closed")
            } else if (leftOpenLED == 0 && leftClosedLED == 1) {
                // change which images are highlighted
                leftOpenImage.image = UIImage(named: "open")
                leftClosedImage.image = UIImage(named: "closed-25%")
            }


            if (rightOpenLED == 1 && rightClosedLED == 0) {
                // change which images are highlighted
                rightOpenImage.image = UIImage(named: "open-25%")
                rightClosedImage.image = UIImage(named: "closed")
            } else if (rightOpenLED == 0 && rightClosedLED == 1) {
                // change which images are highlighted
                rightOpenImage.image = UIImage(named: "open")
                rightClosedImage.image = UIImage(named: "closed-25%")
            }


        } catch let error as NSError {
            print("JSON Error \(error.localizedDescription)")
            //showAlert(alertMessage: "Error retrieving results-check the URL or Server!")
        }
    }





    func CreateJSONMessage() {
        // Create a JSON message to send to Arduino
        // so it knows to update it's own local values
        // of parameters and then open/close doors as
        // necessary

        // define a JSON object to be a dictionary
        let jsonObject: NSMutableDictionary = NSMutableDictionary()

        // set values in dict
        jsonObject.setValue(leftOpenLED, forKey: "leftOpenLED")
        jsonObject.setValue(leftClosedLED, forKey: "leftClosedLED")
        jsonObject.setValue(rightOpenLED, forKey: "rightOpenLED")
        jsonObject.setValue(rightClosedLED, forKey: "rightClosedLED")
        //print("json object = \(jsonObject)")

        do {
            /*
            let jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: JSONSerialization.WritingOptions()) as NSData
            let jsonString = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue) as! String
            print("json string = \(jsonString)")
            */

            // create the url with NSURL
            let url = NSURL(string: arduinoURL)
            let request = NSMutableURLRequest(url: url! as URL)
            let session = URLSession.shared
            request.httpMethod = "POST"
            request.httpBody = try? JSONSerialization.data(withJSONObject: jsonObject, options: [])
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            request.addValue("application/json", forHTTPHeaderField: "Accept")

            let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
                print("Response: \(response)")})

            task.resume()
        } catch _ {
            print ("JSON Failure")
        }

    }
}

2 个答案:

答案 0 :(得分:1)

我不认为您编写的代码存在问题。这就是iOS应用程序状态的维护方式。

如果应用程序暂时不使用,操作系统会将应用程序转换为挂起模式,此时应用程序的三个内存将被释放。

因此,如果您在一段时间后重新启动应用程序,操作系统会将其视为初始启动。

我建议你阅读背景转换周期

https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html

答案 1 :(得分:0)

这可能是一个评论,但它有点长。

我也有兴趣看到你的AppDelegate,但我怀疑它只是默认值。

首先,由于您在CreateJSONMessage方法中使用try?而非try,因此您的catch不执行任何操作(并应生成警告)。

有几个问题要看是否是生命问题。 当你回到应用程序(过了一段时间后它开始出现错误行为)时,你会看到你的启动画面吗? 如果你重新启动设备会发生什么,我认为它的行为符合预期?

要查看是否因为您的某个试用版块而崩溃,请更改您的试用版?尝试,然后在每个catch中,将错误写入应用程序中的文本视图。

catch let error {
  // write error to some new "debug" text field. 
}