【问题标题】:Xcode JSON string to receive dataXcode JSON 字符串接收数据
【发布时间】:2019-03-03 10:27:56
【问题描述】:

我不确定我是否设置正确,但我正在尝试使用 JSON 字符串从服务器接收 iPhone 应用程序上的数据。我为字符串创建了标签,但没有收到数据。我知道服务器正在工作,如果我从命令行运行 curl 我会收到数据。有人可以指出我正确的方向。

ViewController.swift

导入 UIKit

类 TemperatureWebServer: UIViewController, TemperatureWebServiceDelegate {

@IBOutlet var currentTempLabel: UILabel!
@IBOutlet var lastUpdatedLabel: UILabel!

private var webService = TemperatureWebService()

override func viewDidLoad() {
    super.viewDidLoad()
    webService.delegate = self
    webService.startConnection()
}

func temperatureReceived(temperature: String, date: String)
{
    currentTempLabel.text = "\(temperature) °C"
    lastUpdatedLabel.text = "\(date)"
}

}

TemperatureWebServer.swift

导入基础 导入 UIKit

protocol TemperatureWebServiceDelegate: class {func temperatureReceived(temperature: String, date: String)}

类 TemperatureWebService: NSObject, URLSessionDelegate {

弱 var 委托:TemperatureWebServiceDelegate?

var data = NSMutableData()
var jsonResult: NSArray = []

func startConnection()
{
    let url = URL(string: "http://192.168.0.10/tempjson.php")!
    let request = URLRequest(url:url,cachePolicy:.reloadIgnoringLocalCacheData,timeoutInterval: 60.0)
    URLSession.shared.dataTask(with:request)
    {
        (data,response,error) in
        if (error as NSError?) != nil
        {
            return
        }
        let response = response as! HTTPURLResponse;

        guard (200...299).contains(response.statusCode)

            else
        {
            return
        }
        _ = data!
        }
        .resume()


}

private func connection(connection: URLSessionConfiguration!, didReceiveData data: NSData!)
{
    self.data.append(data as Data)
}

func connectionDidFinishLoading(connection: URLSession!)
{

    getLatestTempReading();
}

func getLatestTempReading()
{
    let dictionary: NSDictionary = jsonResult.lastObject as! NSDictionary
    let tempValue = dictionary.object(forKey: "Temp") as! String
    let dateValue = dictionary.object(forKey: "Date") as! String


    if (delegate != nil)
    {
        if (delegate != nil)
        {
            delegate?.temperatureReceived(temperature: tempValue, date: dateValue)
        }
    }
}

}

AppDelegate 导入 UIKit

@UIApplicationMain 类 AppDelegate:UIResponder,UIApplicationDelegate,TemperatureWebServiceDelegate { func temperatureReceived(温度:字符串,日期:字符串){

}


var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    return true
}

func applicationWillResignActive(_ application: UIApplication) {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}

func applicationDidEnterBackground(_ application: UIApplication) {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

func applicationWillEnterForeground(_ application: UIApplication) {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

func applicationDidBecomeActive(_ application: UIApplication) {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

func applicationWillTerminate(_ application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

}

【问题讨论】:

  • 我没有看到对 startConnection() 的呼叫。另外,不要去掉NSURLConnection,更喜欢URLSession
  • 嗨拉尔姆,谢谢。我在上面的代码中添加了 startConnection()。对吗?

标签: ios json string xcode


【解决方案1】:

当你跑步时

let webService = TemperatureWebService()

您正在创建一个在函数(viewWillAppear) 执行时存在的局部变量。一旦viewWillAppear 完成,它将删除对该变量的本地引用,这意味着不再有对它的强引用,这意味着它将被释放。这就是为什么你的委托电话永远不会被调用并且你没有得到你的数据的原因。相反,如果您在类 ViewController 中创建一个局部变量,例如:

class ViewController: UIViewController, TemperatureWebServiceDelegate {

    @IBOutlet var currentTempLabel: UILabel!
    @IBOutlet var lastUpdatedLabel: UILabel!
    private var webService = TemperatureWebService()

    override func viewDidLoad() {
        super.viewDidLoad()
        webService.delegate = self
        webService.startConnection()
    }

您在哪里为您的标签制作网点。虽然您的 ViewController 类存在于内存中,但它会强烈引用您的 TemperatureWebService 类。然后你也可以一起删除你的viewWillAppear 函数。您还缺少对startConnection() 的函数调用,例如提到的larme

还有一点值得一提:

var delegate: TemperatureWebServiceDelegate?

将导致TemperatureWebService 保持对其委托的强引用。我们应该将此属性标记为weak,否则我们将在这里有一个保留循环,其中ViewController -> TemperatureWebService -> ViewController,因此即使我们尝试清理ViewController,它们也永远不会被释放

weak var delegate: TemperatureWebServiceDelegate? // to make sure we don't make retain cycles

【讨论】:

  • 嗨,克里斯,感谢您在这方面的帮助。我试图添加'弱 var 委托。但是,该程序说我不能为此添加“弱”,因为它是“非类绑定”。
  • @00BEAR 当你声明你的协议时:`protocol TemperatureWebServiceDelegate { func temperatureReceived(temperature: String, date: String) } `你需要在协议名称之后添加:class,这样我们就可以弱化反对它的引用。它应该看起来像:`协议TemperatureWebServiceDelegate:类{func temperatureReceived(温度:字符串,日期:字符串)}`
  • 我就是这样做的。但是,我仍然没有做正确的事情。我没有任何错误,但标签框中也没有值。
  • 这很容易从显示在标签中更改为表格视图吗?这甚至可以解决我的问题吗?
  • 00BEAR 你能概括一下你的问题吗?我不确定我是否遵循您在这里的要求。
猜你喜欢
  • 2020-08-14
  • 2013-06-14
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2021-08-01
  • 2021-10-12
相关资源
最近更新 更多