使用Swift

时间:2015-10-12 14:14:52

标签: ios

如何使用另一个类中的函数的字符串值来更新ViewController上的UILabel? 这是我的代码:

查看控制器:

导入UIKit

类ViewController:UIViewController,dataEnterdDelegate {

@IBOutlet weak var auaTempLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    let weather2 = WeatherService2()
    weather2.getWeatherData("Oranjestad,AW") 
}

**func userDidEnterInformation(info: NSString)
{
    testLabel!.text = info as String
}**

func setLabel2(information: String)
{
    auaTempLabel.text = information
}

另一个名为WeatherService2的类包含以下代码:

**protocol dataEnterdDelegate{
func userDidEnterInformation(info:NSString)
}**

Class WeatherService2{
var currentTempeture:String?
let targetVC = ViewController()
**var delegate: dataEnterdDelegate?**

func getWeatherData(urlString:String)
{
    let url = NSURL(string: urlString)!
    let sqlQuery =  "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\"\(url)\")"

    let endpoint = "https://query.yahooapis.com/v1/public/yql?q=\(sqlQuery)&format=json"

    let testString = (String(endpoint))
    getData(testString)
}

func getData(request_data: String)
{
    let requestString:NSString = request_data.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!

    let url_with_data = NSURL(string: requestString as String)!
    let task = NSURLSession.sharedSession().dataTaskWithURL(url_with_data){
        (data, response, error) in dispatch_async(dispatch_get_main_queue(), {
            if data == nil
            {
                print("Failed loading HTTP link")

            }else{
                self.setLabel(data!)
            }
        })
    }
    task.resume()



}

func setLabel(weatherData:NSData)
{
    enum JSONErrors: ErrorType
    {
        case UserError
        case jsonError
    }

    do{
        let jsonResults = try NSJSONSerialization.JSONObjectWithData(weatherData, options: .AllowFragments)

        if let city = jsonResults["query"] as? NSDictionary
        {
            if let name = city["results"] as? NSDictionary
            {
                if let channel = name["channel"] as? NSDictionary
                {
                    if let item = channel["item"] as? NSDictionary
                    {
                        if let condition = item["condition"] as? NSDictionary
                        {
                            if let temp = condition["temp"] as? String
                            {
                                setTemp(temp)
                                **delegate!.userDidEnterInformation(temp)**   
                            }
                        }
                    }
                }

            }
        }
    }

    catch {
        print("Failed to load JSON Object")

    }


}


func setTemp(tempeture:String)
{
    self.currentTempeture = tempeture
}

func getTemp() ->String
{
    return self.currentTempeture!
}

}

代码运行正常,但是当我尝试更新ViewController中的UILabel时,我收到错误“致命错误:在展开可选值时意外发现nil”。 当我在视图控制器类中使用print("The return value is: "+information)时,它会正确打印返回值。 这就是我现在感到困惑的原因,因为我不知道为什么我仍然会在尝试使用此值来更新我的UILabel时遇到“致命错误:在展开可选值时意外发现nil”。

任何人都可以帮我解决这个问题吗?

提前致谢

2 个答案:

答案 0 :(得分:0)

为此你必须创建委托方法。

viewController中,您可以创建委托方法并从获得响应的位置调用它并设置viewController.delegate = self

我无法解释更多你必须搜索它,它将100%工作。

一切顺利。

答案 1 :(得分:0)

我设法通过执行以下操作来解决此问题: 我创建了以下类 - 项目 - 条件 - 频道 这些类实现 JSONPopulator 协议。 JSONPopulator 协议:

protocol JSONPopulator 
{
    func populate(data:AnyObject)
}

项目类:

class Item: JSONPopulator
{
var condition:Condition?

func getCondition() ->Condition
{
    return condition!
}

func populate(data: AnyObject)
{
    condition = Condition()
    condition?.populate(data)
}
}

条件类:

class Condition:JSONPopulator
{

var arubaTemp:String?

var channel:NSDictionary!

func getArubaTemp()->String
{
    return arubaTemp!
}

func getBonaireTemp() ->String
{
    return bonaireTemp!
}

func getCuracaoTemp()->String
{
    return curacaoTemp!
}

func populate(data: AnyObject)
{
    if let query = data["query"] as? NSDictionary
    {
        if let results = query["results"] as? NSDictionary
        {
            if let channel = results["channel"] as? NSDictionary
            {
                self.channel = channel
                if let location = channel["location"] as? NSDictionary
                {
                    if let city = location["city"] as? String
                    {
                        if city.containsString("Oranjestad")
                        {
                            switch city
                            {
                            case "Oranjestad":
                                arubaTemp = getTemp()
                                print(arubaTemp)
                            default:
                                break
                            }

                        }
                    }
                }
            }
        }
    }
}



func getTemp() ->String
{
    var temp:String?
    if let item = self.channel["item"] as? NSDictionary
    {
        if let condition = item["condition"] as? NSDictionary
        {
            if let tempeture = condition["temp"] as? String
            {
                print(tempeture)
                temp = tempeture
            }
        }
    }
    print(temp)
    return temp!
}

}

频道类:

class Channel: JSONPopulator
{
    var item:Item?
    var unit:Unit?
    var request_city:String?

    func setRequestCity(request_city:String)
    {
        self.request_city = request_city
    }

    func getRequestCity() ->String
    {
        return request_city!
    }

    func getItem() -> Item
    {
        return item!
    }

    func getUnit() -> Unit
    {
        return unit!
    }

    func populate(data: AnyObject)
    {
        item = Item()
        item?.populate(data)      
    }

}

WeatherService 类,用于处理解析JSON对象的功能。该类实现了 WeatherServiceCallBack 协议。 WeatherServiceCallBack 协议:

protocol WeatherServiceCallBack
{
    func arubaWeatherServiceService( channel:Channel)
    func arubaWeatherServiceFailure()
}

WeatherService 类:

class WeatherService
{
    var weatherServiceCallBack:WeatherServiceCallBack
    var requestCity:String?

    init(weatherServiceCallBack: WeatherServiceCallBack)
{
    self.weatherServiceCallBack = weatherServiceCallBack
}

internal func checkCity(city:String)
{
    switch (city)
    {
        case "Oranjestad,AW":
        requestCity = city
        getWeatherData(requestCity!)
    default:
        break
    }

}


func getWeatherData(urlString:String)
{
    let url = NSURL(string: urlString)!

    let sqlQuery =  "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\"\(url)\")"

    let endpoint = "https://query.yahooapis.com/v1/public/yql?q=\(sqlQuery)&format=json"


    let testString = (String(endpoint)
    executeTask(testString)
}

func executeTask(request_data: String)
{
    let requestString:NSString = request_data.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!

    let url_with_data = NSURL(string: requestString as String)!

    let task = NSURLSession.sharedSession().dataTaskWithURL(url_with_data){
        (data, response, error) in dispatch_async(dispatch_get_main_queue(), {
            if data == nil
            {
                print("Failed loading HTTP link")

            }else{
                self.onPost(data!)
            }
        })
    }
    task.resume()

}

func onPost(data:NSData)
{
    enum JSONErrors: ErrorType
    {
        case UserError
        case jsonError
    }

    do{
        let jsonResults = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
        print(jsonResults)

        if let city = jsonResults["query"] as? NSDictionary
        {
            if let name = city["count"] as? Int
            {
                if name == 0
                {
                    weatherServiceCallBack.arubaWeatherServiceFailure()
                }
            }

        }

        if let requestCity_check = jsonResults["query"] as? NSDictionary
        {
            if let results = requestCity_check["results"] as? NSDictionary
            {
                if let channel = results["channel"] as? NSDictionary
                {
                    if let location = channel["location"] as? NSDictionary
                    {
                        if let city = location["city"] as? String
                        {
                            requestCity = city
                            let channel = Channel()
                            channel.setRequestCity(requestCity!)
                            channel.populate(jsonResults)
                            weatherServiceCallBack.arubaWeatherServiceService(channel)
                        }

                    }

                }

            }
        }


    }catch {
        print("Failed to load JSON Object")
    }

}

}

ViewController 类中(我向UILabel添加了一些动画,以便它可以从华氏温度转换为摄氏温度):

class ViewController: UIViewController, WeatherServiceCallBack
{
    var weather:WeatherService?
    var aua_Tempeture_in_F:String?
    var aua_Tempeture_in_C:String?
    var timer = NSTimer()
    @IBOutlet var aua_Temp_Label: UILabel!
    let animationDuration: NSTimeInterval = 0.35
    let switchingInterval: NSTimeInterval = 5  //10


    override func viewDidLoad() {
    super.viewDidLoad()
    weather = WeatherService(weatherServiceCallBack: self)
    weather?.checkCity("Oranjestad,AW")

}

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

    func animateTemptext()
    {

self.timer = NSTimer.scheduledTimerWithTimeInterval(7.0, target: self, selector: Selector("tempConvertionTextSwitch"), userInfo: nil, repeats: true)


    }

func setTempinCelsius(temp_string:String)
{

    aua_Tempeture_in_F = "\(temp_string)°F"
    let convertedString = convertFahrenheittoCelsius(temp_string)
    aua_Tempeture_in_C = "\(convertedString)°C"
    aua_Temp_Label.text = aua_Tempeture_in_C
    animateTemptext()
}

func convertFahrenheittoCelsius(currentTemp:String) ->String
{
    let tempTocelsius = (String(((Int(currentTemp)! - 32) * 5)/9))
    return tempTocelsius
}

@objc func tempConvertionTextSwitch()
{
    CATransaction.begin()
    CATransaction.setAnimationDuration(animationDuration)
    CATransaction.setCompletionBlock{
        let delay = dispatch_time(DISPATCH_TIME_NOW,Int64(self.switchingInterval * NSTimeInterval(NSEC_PER_SEC)))
        dispatch_after(delay, dispatch_get_main_queue())
            {

        }

    }
    let transition = CATransition()
    transition.type = kCATransitionFade
    if aua_Temp_Label.text == aua_Tempeture_in_F
    {

        aua_Temp_Label.text = aua_Tempeture_in_C
    }else if aua_Temp_Label.text == aua_Tempeture_in_C
    {

        aua_Temp_Label.text = aua_Tempeture_in_F
    }else if aua_Temp_Label == ""
    {
        aua_Temp_Label.text = aua_Tempeture_in_C
    }
    aua_Temp_Label.layer.addAnimation(transition, forKey: kCATransition)
    CATransaction.commit()

}



func arubaWeatherServiceFailure() {

}

func arubaWeatherServiceService(channel: Channel)
{
    let requested_city = channel.getRequestCity()
    let items = channel.getItem()
    let aua_Temp = items.getCondition().getArubaTemp()
    setTempinCelsius(aua_Temp)

}

}

参考:

  • iOS 8 Swift编程手册iOS应用程序解决方案示例

  • 使用Swift Swift,Xcode和Cocoa Basics的iOS 8编程基础

希望它有助于曾经遇到同样问题的人