用Swift實現一款天氣預報APP(一)


這個系列的目錄:

用Swift實現一款天氣預報APP(一)

用Swift實現一款天氣預報APP(二)

用Swift實現一款天氣預報APP(三)

 

Swift作為現在蘋果極力推廣的語言,發展的非常快。這個語言就和她的名字一樣,比OC減少了很多的文件和代碼量。頭文件,bye bye啦,再不用查個代碼上下的頭文件源文件切換了。而且語言本身也增加了很多的安全性的考慮,比如類的初始化個階段的檢查等。不按照規定的寫就不能編譯通過!本文假定你有一定的編程基礎,和一定的Swift基礎。如果木有的話,請看這里迅速補起。

本文就用Swif寫一個APP,讓各位一起來體會一下Swift到底是好在了哪里。為了簡單,教程會使用Storyboard,而不是手動的添加Controller以及Controller的View的各種視圖。使用Storyboard可以減少很多的代碼量。這個會在之后的教程中體現出來。任何的視圖跳轉都是按下Ctrl之后的連線,都是Segue。這些標准的跳轉都不用寫一行代碼。

現在的APP,沒有哪個是孤立的存在在用戶的手機里的。除了,額,類似於2048這樣的APP沒有明顯的連接后台的服務器,但是,你的位置等信息都傳到了后台的服務器。所以,我們的教程還要涉及到網絡連接。先用SDK內置的,然后再講解現在十分流行的AFNetworking。

這個天氣預報的APP看起來會是這樣的:

現在進入正題,創建我們的項目:

選擇一個Single View的模版。然后:

之后填寫項目名稱,Swift Weather以及其他的如,組織名稱等。之后一直下一步,確定就創建了項目。

這個時候你會看到除了Storyboard居然會有一個xib文件。這個xib文件不是用來在APP中結合使用ViewController的。而是專門用來適配不同個屏幕分辨率的。也就是有了這個叫做LaunchScreen.xib的文件,就不用在每一個分辨率下都做一張LaunchImage的圖片了。

這里有一點需要注意。這個LaunchScreen的nib文件是不能像之前我們常用到的xib文件一樣設置File Owner之后綁定IBOutlet和IBAction的。因為這個nib文件在加載的時候APP還沒有加載完成,所以即使綁定了File Owner的ViewControler也是用不了的。

下面我們開始在Storyboard中穿件不同的Scene(對應到一個UIViewController)並把他們連接起來。在這之前需要明白我們的這個APP會如何工作呢?這里,我們的比較簡單,不要想成新浪天氣、墨跡天氣。因為,這個是課后作業。看完教程以后由你自己去實現一個類似的活着更好的天氣預報的客戶端。我們的Demo天氣預報APP相對簡單。用戶打開APP后直接進入APP天氣的主界面查看天氣。之后用戶可以點擊導航欄左側的“City”按鈕更換城市活着點擊右側的“Refresh”按鈕來實時的刷新天氣數據。

主界面的頭看起來會是這個樣子的:

好的,回到Storyboard上來。首先從右側動Utilities邊欄中拖動一個UINavigationController:

到Storyboard上來,並設定位Initial Controller, 如圖:

 拖動一個UINavigationController會自帶一個RootViewController上來。選中這個Controller刪了。我們要用自己的Controller作為RootViewController。刪了之后從右側到菜單中選擇一個ViewController,並把鼠標放到UINavigationController上,然后按下Ctrol鍵,用鼠標緩緩的拖一條藍藍的細線到你新家上來的ViewController上。放開Ctrl。在彈出的菜單里選擇最下面的relationship->rootViewController。連接完成之后就會產生一個segue。

這個APP已經可以運行起來了,按下Command+R,模擬器中就會出現這個APP。雖然現在的界面還是很簡單的。

基本的結構已經有了,下面添加主界面元素。仔細觀察界面,可以發現一個規律:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

大體的結構是在最上面顯示地點,下面的大太陽是當前的天氣狀況,再下面是當前的溫度。在主界面下面的一排小圖是分時段的天氣和溫度。顯示的順序都是時間,當時天氣的圖片和當時的溫度。小的結構都是上面文字,中間圖片,下面又是文字。最大的不同在於主界面的大圖部分上面顯示的是地名,而下面分時間顯示天氣部分,顯示的是時間。所以,正題的結構都差不過,從上到下的順序顯示了文字圖片然后文字。先記住這個,在后面會用到這個規律。現在先按照這樣的規律把界面上需要的元素拖動到ViewController的View上。使用快捷鍵Option+Command+L,之后輸入label。你會在右側的邊欄里出現UILabel這個控件,拖動到View上。其他的依次都拖動到主界面上。然后在Storyboard中綁定Controller文件。主界面對應的代碼文件是MainViewController,並在代碼中加入各個控件對應的IBOutlet。就像這樣:

    @IBOutlet weak var icon : UIImageView!
    @IBOutlet weak var temperature : UILabel!
    @IBOutlet weak var loading : UILabel!
    @IBOutlet weak var location : UILabel!
    @IBOutlet weak var time1: UILabel!
    @IBOutlet weak var time2: UILabel!
    @IBOutlet weak var time3: UILabel!
    @IBOutlet weak var time4: UILabel!
    @IBOutlet weak var image1: UIImageView!
    @IBOutlet weak var image2: UIImageView!
    @IBOutlet weak var image3: UIImageView!
    @IBOutlet weak var image4: UIImageView!
    @IBOutlet weak var temp1: UILabel!
    @IBOutlet weak var temp2: UILabel!
    @IBOutlet weak var temp3: UILabel!
    @IBOutlet weak var temp4: UILabel!

現在就可以綁定Storyboard的控件和MainViewController中的IBoutlet了。綁定的順序:先、在Storyboard中選中主界面的Scene,二、點一下圈住的地方,這個時候在有邊欄里就會發現有IBOutlet的一個section里面就都是我們剛剛在代碼中定義的屬性。如左圖,有icon這個屬性就是在上面的代碼中有提到的定義的屬性。

綁定的時候把鼠標放到比如icon的后面的小圈圈上面,然后按住Ctrl鍵,拖動鼠標到你要綁定的控件上,放開Ctrl鍵綁定就完成了。就像左圖中的textLabel一樣的效果。點那個小叉叉就可以斷開控件和代碼中的對應屬性的綁定。

 

 

綁定好之后就可以在代碼中修改這些控件的值等屬性了。綁定好的:

 這里假定你已經把界面的元素都按照主界面樣子擺好了,設定好,並且已經綁定。如果有任何問題,請參考源代碼。

這里必須提一件事。之所以很多公司的開發都不使用nib文件和現在的storyboard。就是因為,大家也看到了,使用nib或者storyboard文件會有很多的名稱,稍微的修改就可能忘記了什么地方沒有重新綁定。沒有綁定控件的,運行起來的時候可能就會出現崩潰的情況。因為,根據key-value的方式存取控件的時候,沒有綁定的找不到。其他還有很多需要設定名稱的地方還包括IBAction還有Segue等。雖然,Storyboard有這個不好的地方。不過對於個人開發者是切實的減少了代碼量。也大大的提高了開發速度!所以Storyboard的優點還是很明顯的。

當全部的控件都擺好之后看起來就是這個樣子的了。

 

以上的內動幾乎都在說界面的事情了。你會看到還有兩個地方沒有提到。一個是City,一個是Refresh。這兩個按鈕式用來更換城市和刷新數據的。點了City之后彈出界面,用戶可以選擇一個另外的城市,查看該地的天氣信息。點擊Refresh之后可以重新獲取當地的天氣數據,並刷新主界面的數據。在City按鈕的界面元素中會涉及到一個“unwind segue”的知識點。比較簡單。放在下面的教程中繼續講解。

咱們的天氣都是根據用戶所在的位置來獲取和顯示的。至少在用戶第一次進入APP的時候,APP自動獲取用戶的地理位置信息,並根據這個位置信息訪問服務器信息獲取天氣數據。所以,首要的問題就是后去用戶的地理位置,也就是經緯度。

詳細的關於在iOS8下獲取地理位置的方法可以看這篇。這里簡單的說一下。獲取位置信息都是用到CoreLocation框架。在Xcode6中無需再專門的做引入框架的操作。只要在代碼中用import 看框架名稱就可以。

import UIKit
import CoreLocation //獲取地理位置

要獲取用戶的地理位置是需要用戶的同意的,所以首先需要在代碼中請求用戶的同意(在iOS8中)。請求用戶的同意時的文字則一定要在項目的plist文件中配置。這個plist中的配置是必須的!否則,APP運行起來也獲取不了用戶的地理位置。

獲取地理位置的方法和iOS的其他版本都是一樣的,設定代理,在代理中獲取地理位置,或者處理獲取信息中產生的錯誤。

class ViewController: UIViewController, CLLocationManagerDelegate

上面是實現LocationManagerDelegate,下面是指定代理,設置精度和請求用戶同意等。

        self.locationManager.delegate = self;
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.distanceFilter = kCLLocationAccuracyKilometer
        if self.locationManager.respondsToSelector("requestAlwaysAuthorization") {
            println("requestAlwaysAuthorization")
            self.locationManager.requestAlwaysAuthorization()
        }

這一句if self.locationManager.respondsToSelector("requestAlwaysAuthorization")是為了和iOS8之前的系統兼容。

最后看看LocationManager的代理如何獲取地理位置和如何處理錯誤。

//MARK: CoreLocationManagerDelegate
    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!){
        println("get location")
        var location:CLLocation = locations[locations.count-1] as CLLocation
        
        if (location.horizontalAccuracy > 0) {
            self.locationManager.stopUpdatingLocation()
            println(location.coordinate)

            self.textLabel.text = "latitude \(location.coordinate.latitude) longitude \(location.coordinate.longitude)"
        }
    }
    
    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
        println(error)
        self.textLabel.text = "get location error"
    }

這里的錯誤處理,只是在顯示具體的經緯度的Label中顯示了出錯的文字。為了更好的用戶體驗,錯誤的提示可以采用更友好的方法。這里只簡單說到這里。

這個APP的第一部分就先介紹到這里。更多內容會在后面的教程中繼續解說。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM