2015-06-30 3 views
0

У меня есть функция, показанная ниже, которую я хотел бы постоянно обновлять. Он берет данные с веб-страницы, и каждый раз так, что веб-страница обновляется, чтобы отражать текущую информацию. Есть ли способ, чтобы я мог поймать это обновление и отразить это в своем приложении? Я довольно новичок в программировании Swift и iOS. Некоторые из сделанного кода кажутся очень странными, но в настоящее время он работает независимо от того, какая песня играет при первом открытии приложения (то есть, он обновляет текст, чтобы показать, что эта песня играет, но не обновляется позже).Постоянно обновляйте UILabel в Swift

let url = NSURL(string: "http://api.vicradio.org/songs/current")! 
    let request = NSMutableURLRequest(URL: url) 

    let session = NSURLSession.sharedSession() 
    let task = session.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) in 

    if error != nil { 
     return 
    } 

    let name = NSString(data: data!, encoding: NSUTF8StringEncoding) as! String 
    var songName = "" 
    var artistName = "by " 
    var quoteNumber = 0 

    for character in name.characters { 

     if character == "\"" { 
      quoteNumber++ 
     } 

     if quoteNumber == 3 && character != "\"" { 
      songName += String(character) 
     } else if quoteNumber == 7 && character != "\"" { 
      artistName += String(character) 
     } 

    } 

    if (songName != "no song metadata provided") { 
     self.SongNowText.text = songName 
     self.ArtistNowText.text = artistName 
     self.SongNowText.setNeedsDisplay() 
     self.ArtistNowText.setNeedsDisplay() 
    } else if (songName == "no song metadata provided") { 
     self.SongNowText.text = "The Best of What's Next!" 
     self.ArtistNowText.text = "only on VIC Radio" 
    } 

    } 

    task!.resume() 

ответ

0

Похоже, что URL-адрес, к которому вы обращаетесь, представляет собой конечную точку API, выпускающую JSON. Я настоятельно рекомендую использовать NSJSONSerialization.JSONObjectWithData, чтобы проанализировать тело ответа в словаре и использовать это вместо того, чтобы опрокинуть свое собственное решение, посчитав кавычки.

Обратный вызов dataTaskWithURL выполняется в фоновом потоке. Избегайте обновления пользовательского интерфейса на чем-либо помимо основного потока, поскольку это может вызвать проблемы. Используйте dispatch_async для выполнения вашей функции обновления пользовательского интерфейса в основном потоке, как в примере.

Все, что вы можете сделать с помощью этого API, - это отправить его и прочитать ответы. Вы можете опросить конечную точку через регулярный промежуток времени, пока приложение открыто и получите достойные результаты. NSTimer - это один из способов сделать это, и для этого требуется, чтобы вы поместили метод, который хотите выполнить повторно, в класс, наследующий из NSObject, потому что он зависит от отправки сообщения стиля Objective-C.

Бросьте это в детской площадке и попробовать:

import Cocoa 
import XCPlayground 
XCPSetExecutionShouldContinueIndefinitely() 

class RadioDataAccessor : NSObject { 
    private let callback: [String : AnyObject] -> Void 

    init(callback: [String : AnyObject] -> Void) { 
     self.callback = callback 

     super.init() 

     NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, 
      selector: "updateData", userInfo: nil, repeats: true) 
     // just so it happens quickly the first time 
     updateData() 
    } 

    func updateData() { 
     let session = NSURLSession.sharedSession() 
     let url = NSURL(string: "http://api.vicradio.org/songs/current")! 
     session.dataTaskWithURL(url) { data, response, error in 
      if error != nil { 
       return 
      } 

      var jsonError = NSErrorPointer() 
      let json = NSJSONSerialization.JSONObjectWithData(data, 
       options: NSJSONReadingOptions.allZeros, 
       error: jsonError) as? [String : AnyObject] 

      if jsonError != nil { 
       return 
      } 
      dispatch_async(dispatch_get_main_queue()) { self.callback(json!) } 

     }.resume() 
    } 
} 

RadioDataAccessor() { data in 
    println(data) 
} 

Вы можете сохранить таймер переменной и выставить функцию, которая позволяет аннулировать его.