2015-11-14 49 views
1

swift新手在這裏。我試圖讓我簡單的核心位置應用程序獲取座標後自動檢索數據locationManager。 我已經實現單獨的類不能讓我的主視圖控制器負責太多的任務在這裏的樣子:如何獲得已經實例化的ViewController的引用?

import Foundation 
import CoreLocation 

class CoreLocationController : NSObject, CLLocationManagerDelegate { 

var locationManager = CLLocationManager() 

var lastCoordinates: (lat: Double, lon: Double)? 

override init() { 
    super.init() 
    self.locationManager.delegate = self 
    self.locationManager.requestWhenInUseAuthorization() 
    self.locationManager.distanceFilter = 3000 
    self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer 

} 

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

    let location = locations.last! as CLLocation 

    self.lastCoordinates = (location.coordinate.latitude, location.coordinate.longitude) 
    print("didUpdateLocations: \(location.coordinate.latitude), \(location.coordinate.longitude)") 

} 

func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 
    print("didChangeAuthorizationStatus") 

    switch status { 
    case .NotDetermined: 
     print(".NotDetermined") 
     break 

    case .AuthorizedWhenInUse: 
     print(".AuthorizedWhenInUse") 
     self.locationManager.startUpdatingLocation() 
     break 

    case .Denied: 
     print(".Denied") 
     break 

    default: 
     print("Unhandled authorization status") 
     break 

    } 
} 

func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { 
    } 
} 

我當然在AppDelegate.swift

初始化它
import UIKit 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate { 

var window: UIWindow? 

var coreLocationController: CoreLocationController? 

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 

    self.coreLocationController = CoreLocationController() 
    return true 
} 

現在我的主ViewController點擊按鈕後正在執行retrieveWeatherForecastappDelegate傳遞給它來獲得CoreLocationController.lastCoordinates屬性的參考。我得出結論,爲了在啓動後立即獲取座標後執行retrieveWeatherForecast,最好的方法是在locationManager func(具有didUpdateLocations參數的那個)中運行此方法。爲了做到這一點,我將需要有參考ViewController運行實例進行某事像:

runningViewControlerinstance.retrieveWeatherForecast(runningViewControlerinstance.appDel) 

主要ViewController代碼:

import UIKit 

class ViewController: UIViewController { 

@IBOutlet weak var currentTemperatureLabel: UILabel? 
@IBOutlet weak var currentHumidityLabel: UILabel? 
@IBOutlet weak var currentPrecipitationLabel: UILabel? 
@IBOutlet weak var currentWeatherIcon: UIImageView? 
@IBOutlet weak var currentWeatherSummary: UILabel? 
@IBOutlet weak var refreshButton: UIButton? 
@IBOutlet weak var activityIndicator: UIActivityIndicatorView? 

let appDel = UIApplication.sharedApplication().delegate! as! AppDelegate 

private var forecastAPIKey: String? 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let path = NSBundle.mainBundle().pathForResource("APIkeys", ofType: "plist") 
    let dict = NSDictionary(contentsOfFile: path!) 

    self.forecastAPIKey = dict!.objectForKey("forecastAPIKey") as? String 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
} 

func retrieveWeatherForecast(appDel: AppDelegate) { 
    let currentCoordinates :(lat: Double, lon: Double) = (appDel.coreLocationController?.lastCoordinates)! 

    let forecastService = ForecastService(APIKey: forecastAPIKey!) 
    forecastService.getForecast(currentCoordinates.lat, lon: currentCoordinates.lon) { 
     (let currently) in 

     if let currentWeather = currently { 

      dispatch_async(dispatch_get_main_queue()) { 

       if let temperature = currentWeather.temperature { 
        self.currentTemperatureLabel?.text = "\(temperature)º" 
       } 

       if let humidity = currentWeather.humidity { 
        self.currentHumidityLabel?.text = "\(humidity)%" 
       } 

       if let precipitation = currentWeather.precipProbability { 
        self.currentPrecipitationLabel?.text = "\(precipitation)%" 
       } 

       if let icon = currentWeather.icon { 
        self.currentWeatherIcon?.image = icon 
       } 

       if let summary = currentWeather.summary { 
        self.currentWeatherSummary?.text = summary 
       } 

       self.toggleRefreshAnimation(false) 

      } 


     } 
    } 
} 

@IBAction func refreshWeather() { 
    toggleRefreshAnimation(true) 
    retrieveWeatherForecast(appDel) 
} 

func toggleRefreshAnimation(on: Bool) { 
    refreshButton?.hidden = on 
    if on { 
     activityIndicator?.startAnimating() 
    } else { 
     activityIndicator?.stopAnimating() 
    } 
} 
} 

我會非常感謝任何幫助,意見和建議你快捷的社區,謝謝!

回答

0

如果您有一個單獨的類來處理位置服務(這是一個很好的設計模式)或者應用程序委託,通知的最佳方式是通知任何活動視圖控制器。

通過NSNotificationCenterviewDidAppear中在視圖控制器中註冊並在viewWillDisappear中刪除自己作爲觀察者。有很多文檔來解釋細節。

控制器與異步進程的鬆散耦合比保持對UI對象的引用安全得多。

-1

「當然,我已經在AppDelegate.swift中初始化它」 爲什麼?沒有理由在那裏初始化它,是嗎?初始化它你打算使用它的地方。您viewController需要訪問您的CoreLocationController才能使用,顯示或編輯位置。所以初始化並在那裏使用它,你不必將你的視圖控制器傳遞給你的位置管理器。

+0

這可能會導致多個核心位置控制器。單身模式在這裏顯然是可取的。 – Mundi

+0

好的。由於它是快速的,在CoreLocationController中聲明一個靜態變量(也是一個懶惰變量)也是可能的。 – user965972

相關問題