知识渊博的人,
我正在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")
}
}
}
答案 0 :(得分:1)
我不认为您编写的代码存在问题。这就是iOS应用程序状态的维护方式。
如果应用程序暂时不使用,操作系统会将应用程序转换为挂起模式,此时应用程序的三个内存将被释放。
因此,如果您在一段时间后重新启动应用程序,操作系统会将其视为初始启动。
我建议你阅读背景转换周期
答案 1 :(得分:0)
这可能是一个评论,但它有点长。
我也有兴趣看到你的AppDelegate,但我怀疑它只是默认值。
首先,由于您在CreateJSONMessage方法中使用try?
而非try
,因此您的catch不执行任何操作(并应生成警告)。
有几个问题要看是否是生命问题。 当你回到应用程序(过了一段时间后它开始出现错误行为)时,你会看到你的启动画面吗? 如果你重新启动设备会发生什么,我认为它的行为符合预期?
要查看是否因为您的某个试用版块而崩溃,请更改您的试用版?尝试,然后在每个catch中,将错误写入应用程序中的文本视图。
catch let error {
// write error to some new "debug" text field.
}