Implementing a weather forecast app with Swift (iii)

Source: Internet
Author: User
Tags exit in

Catalog of this series:

Implementing a weather forecast app with Swift (i)

Using Swift to implement a weather forecast app (ii)

Implementing a weather forecast app with Swift (iii)

Through the previous study, a weather forecast app has been basically available. At least you can see the current weather conditions and the weather forecast for the next few hours. However, it is not perfect. What to do if the user wants to know the weather where he is going. Obviously our app doesn't meet the needs of users at this time. And our app needs to get the weather in other cities, but it's very simple. By looking at the weather API, you can find the weather forecast for your local city by just taking the name of the city as a parameter. Api:

Api.openweathermap.org/data/2.5/find?q=london&type=like&mode=xml

Q=london is the parameter that specifies the location in the API. However, you can also make a single exit from here. The name of the city is displayed in English, not "Beijing", that is, the Chinese character is displayed in the city list, but the URL to the API is used when the name of the city is English, or it can be said to be phonetic alphabet.

In this article, our main function is to switch cities, and refresh the weather forecast data. First, add a controller called the city list in storyboard. We need to display a list of cities in the controller, which requires a control that is very common in iOS development:UITableView. After adding a uiviewcontroller , drag a uitableview to this viewcontroller. In this way, the interface is complete.

Below, create the code, select Source, first select your superclass in subclass of Uiviewcontroller, and then name your class. Here is "citylistviewcontroller". Finally in the language one chooses Swift. You should not choose objective-c .

After that all the way next has been done.

A lot of tutorials always like to use Uitableviewcontroller when it comes to UITableView, which is a package with a uiviewcontroller that contains a uitableview. Sometimes, the system encapsulates too much stuff that is not good for developers. In particular, developers dealing with UITableView alone will not take too much time. So, the combination of Uiviewcontroller and UITableView is used here.

Add the properties of the UITableView object that you want to bind in your Viewcontroller file:

var tableview:uitableview!

After selecting in the controller, select the third option in the left-hand column and select the Citylistviewcontroller you just created in the following class. Generally, after you have chosen

After the controller, the Module underClass is automatically set to Current-swift_weather. That is, the name of your project is automatically selected. If you don't have a choice, you'll need to manually add your project name to the module. Otherwise, this viewcontroller is not available. The concept of module is introduced in Swift. The default app is a module. Classes are found in the module of your app. Without the Module name, the app cannot find the code you have associated with this viewcontroller.

After these operations are completed, you have associated the storyboard Viewcontroller with the corresponding code. It is also necessary to correlate the UITableView controls mentioned in the forward article. Click on the controller you just selected and select the rightmost arrow button in the right column and you will see a tableview in it, and the small circle behind him is not associated with the storyboard tableview. Put the mouse on the small circle, press CTRL while moving the mouse to the storyboard uitableview.

So far it has been perfect, but the TableView is not yet available. TableView need to know how many Tableviewcell to display, and what is displayed on each cell. How high each cell is and how many sections there are. Which cell is selected, which cell has been selected to be selected, etc. These are all implemented through the TableView agent. Such agents a total of two, one is called uitableviewdelegate, one is called Uitableviewdatasource.

Therefore, you also need to associate the UITableView's two agents with the controller where the UITableView resides. Select the storyboard UITableView, and then select the last option in the right column. That's the last option. You will see

Put the mouse on the small circle, while pressing the CTRL key, moving the mouse to the controller on the UITableView, exactly said to move here:. All two of these operations are done. After completion, the UITableView is associated with uitableviewdelegate and uitableviewdatasource.

So far, we have created a controller (Scene) in storyboard and put a uitableview on it. A Uiviewcontroller code was created and associated with the controller that was just created. And the UITableView also linked together, but also associated with this uitableview uitableviewdelegate and uitableviewdatasource. uitableviewdelegate and Uitableviewdatasource are protocol in Swift's syntax, which is the interface of other languages, such as Java, C #, Where to inherit where to give the implementation. Since UITableView's delegate and DataSource are all set on his controller, the Citylistviewcontroller in our code needs to inherit Uitableviewdelegate and uitableviewdatasource and achieve these two protocol.

class Citylistviewcontroller:uiviewcontroller, Uitableviewdelegate, Uitableviewdatasource

The following are the implementations of some of the necessary methods in uitableviewdelegate and uitableviewdatasource . Note that these are just a necessary way to uitableview normal display, and there are many methods that are not available for the time being.

The first line is to specify how many sections of the UITableView are in the section partition, and that in one section it will contain multiple cells. Here, there is only one section.

The second line is to specify how many cells are in each section. Because we have only one section, so how many cities have the choice of how many cells. This is subject to different circumstances.

The third line initializes each cell. What a cell looks like is decided by this method.

Line four, which is the method that executes after a cell is selected. When the user chooses a cell, we need to know which one, and send the name of the cell's city in English (or pinyin letters) to the main interface to get weather data for the city.

These are all when you use a uitableview. First create a UITableView controller (Scene) and drag a uitableview on top. Two, create a swift code corresponding to the controller for this scene, and add the UITableView attribute to the code. The controller associated with scene and Swift, the UITableView property of the associated code, and the UITableView in storyboard. Third, associate UITableView's delegate and DataSource to the SWIFT code controller, where they inherit and implement Uitableviewdelegate and Uitableviewdatasource. This part requires more practice and memorization. Because you will find that no application is uitableview. If you can not find uitableview that also may be the developer of the UITableView custom more deep, intuitive can not see it.

One thing to emphasize here is the method of creating the cell in the third row. UITableView cells are not created every time they are used. The phone now has 2G of memory, and the CPU is a few cores. However, its resources are still relatively scarce. If, each cell is created with a new one. Then, users will be very uitableview when they swipe up and down. This is absolutely not allowed for a good app. So Apple also recommended a way to use the cell, if the cell has not been created, then create one. If the cell has already been created, then the cell is re-assigned. The point here is that if a cell has been created, it is only re-assigned and no longer created ! See the following code:

Func TableView (Tableview:uitableview, Cellforrowatindexpath Indexpath:nsindexpath)UITableViewCell {varCell = Tableview.dequeuereusablecellwithidentifier ("Cellidentifier") as?UITableViewCellifCell = =Nil {cell= UITableViewCell (Style:UITableViewCellStyle.Default, Reuseidentifier:"Cellidentifier")} cell?. Textlabel.text =Self.citylist.values.array[indexpath.row]returncell!    }

The cell is first retrieved from the cell's identifier from UITableView. If it is empty, create a cell and specify the cell's identifier. If the cell is not empty, the Textlabel Text property of the cell is re-assigned. However, since we have used the storyboard, we will use it thoroughly. Why does the cell not use storyboard to create it. This saves a lot of code, such as the part of the cell that we reuse here. Locate the UITableViewCell in the right column and drag to the UITableView. Give the cell's identifier a name called "Citycell". Style chooses custom, which means that we want to customize this cell.

Next, add a new Swift code file for this cell. First, Source->cocoa Touch Class. Then select

Binds the SWIFT code class to the cell. Check storyboard here.

After

This cell needs a uilabel to show the Chinese name of the city (this uilabel is just to show what to do when customizing a cell in storyboard, in general there is a textlabel in the cell that can display text). Then add a Label property to the code first:

var citynamelabel:uilabel!

After you add the properties, associate the label that you just added in the cell in this Citynamelabel and storyboard. Repeat the first step mentioned above and select the cell. Then select the last item in the top option in the second step. You'll see Citynamelabel and behind him a small circle. You should know what to do. After associating the property with the storyboard label, go back to the previous method of creating the cell.

    Func TableView (Tableview:uitableview, Cellforrowatindexpath indexpath:nsindexpath), UITableViewCell {        /c1>var citylistcell = Tableview.dequeuereusablecellwithidentifier ("citycell"  as Citylisttableviewcell         = Self.citylist.values.array[indexpath.row]        return  Citylistcell    }

See what's different. Yes, there is no need to get the cell from the TableView cell's multiplexing queue anymore. Because, these are all dealt with in the storyboard. We just have to reassign the cell every time.

So far, the city list is still unavailable. Because, we haven't associated this list with the weather forecast's main interface. Yes, where do users enter the city list? Now we'll associate the main interface with the city list. First, drag a uinavigationcontrollerinto the Storyboard . Cut out the back of the Rootviewcontroller, and put this uinavigationcontroller rootviewcontroller Associated with the city list controller we just created. This similar operation has been described in the first section. If you don't know, you can look at the first part again.

After that, find the city button on the main interface, connect to the newly added uinavigationcontroller , and select Modal in the Action Segue that pops up. . This time to run the app, click on the city will appear just created the Citylistcontroller, the user can click on the above line, but ... Can't go back. Let's deal with the problem now. The development of this work is " Sankai, Encounter Water Bridge." Add the following code in the Mainviewcontroller

@IBAction func dismisscitylistcontroller (segue: uistoryboardsegue) {

println("dismiss Controller")

}

The name can be arbitrary, but the parameter must be of type uistoryboardsegue . Then, right-click Exit in the storyboard's weather forecast main screen and you'll see the method dismisscitylistcontroller you just added in the menu that appears. In this method there is a small circle. The storyboard is filled with such a small circle. Connect this small circle to the Citylistcontroller cell and select selectionin the small popup menu. This means that when the user chooses a cell of UITableView (selection), Citylistcontroller exits with "exit".

This method is the legendary "unwind Segue" to this segue set a identifier for "Backtomain". Connect and run the app later. When you point a city with your finger, the citylistcontroller will be hidden. The user can return to continue operation after the city has been selected.

However, after selecting the city, the main interface shows the original city, and there is no replacement. At that time, we did not add the relevant code. The above adds only to allow the interface to jump under the guidance of segue, but does not change the city and then requests the weather forecast data again. This part of the function is completed below.

Passing data between Uiviewcontroller , we are here to pass the chosen city from Citylistcontroller to Mainviewcontroller. There are many ways to do this, for example, the Notification method you will often use later. After the user chooses a city, it emits a notification, captures the notification in the Mainviewcontroller, and handles it accordingly. It seems very simple to put. But we don't use this method here. Using the notification method will cause some trouble to the maintenance of the code. Where to send, where the acceptance is written separately, it is not easy to maintain the code. We're going to pass the data in a proxy way here. This method is often used between custom controls and Viewcontroller. Specifically to our weather app here, we need to pass data from Citylistcontroller to Mainviewcontroller, then define an interface (protocol) in the Citylistcontroller file. Apple's general naming convention is to add delegate after the name of your controller. This is very good to identify where the definition of delegate, where the use of this delegate.

@objc protocol citylistviewcontrollerdelegate{    func citydidselected (citykey:string)}

This @objc does not have to be added, it is generally shared with other objective-c code when added. Add a property called Delegate in the Citylistviewcontroller. This property is executed when a cell in the Citylistviewcontroller UITableView is selected.

var delegate: Citylistviewcontrollerdelegate?

Here with weak because, we do not want this proxy strong reference (strong) other controller. This causes a circular reference so that the reference count of the controller is not reduced, so it cannot be purged from memory when not in use . Execute at selected time

func TableView (Tableview:uitableview, Didselectrowatindexpath indexpath:nsindexpath) {println ("Did select row \ (indexpath.row)")                //Set Current selected index of city listSelf.selectedindex =Indexpath.rowifSelf.selectedindex! = nil && self.Delegate!=Nil {varCitykey = self.citylist.keys.array[self.selectedindex!] Self.Delegate?. citydidselected (Citykey)} tableview.deselectrowatindexpath (Indexpath, animated:true)    }

To implement the Proxy method in Citylistviewcontroller, you need to implement this protocol in the Mainviewcontroller.

Classuiviewcontrollercllocationmanagerdelegatecitylistviewcontrollerdelegate{  

//mark:city changed delegate func citydidselected (citykey:string) { println ( "selected city \ (citykey)") }
}

The above code is a presumably implementation. The specific code can be viewed in the sample project.

This code executes when you run the app and select a different city. The English name of the selected city appears in the console. Now we need to come to the real. To view the previous code, there is a method for func updateweatherinfo (Latitude: cllocationdegrees, Longitude: cllocationdegrees) will request the server to get the weather forecast after acquiring the user's geographic location. We now need to get the weather forecast based on the name of the city. So, let's go over the Load method updateweatherinfo. Over Load is a method that defines a different method with the same name as one of the other methods.

Func Updateweatherinfo (cityname:string)

The next thing is the URL string problem with the HTTP request in the previous article. There is not much to be described here.

There is one more feature that has not been completed. You'll soon think: Refresh. When the user chooses another city, it needs to return quickly to the weather forecast where the user clicked the refresh. Click Refresh to get the latest geolocation data for the user and request the weather forecast data. This feature has been implemented. When the user enters the main interface, the user's location is automatically obtained and the weather forecast is requested. The refresh feature only needs to regain the user's geographic location in the Refreshaction method, requesting that the weather forecast will be executed automatically when the user's location is obtained. One thing to mention here is that when the weather forecast is successfully obtained, you should stop getting the user's location . Because this will save power to the user! Power saving is also part of the user experience. As a developer, if your app is too much power, and it's not a very fun game, it's not justified.

The code for this series of articles is here.

Read more: Afnetworking is cocoapods loaded in. To learn more about Cocoapods, please see here.

The original version of the code used in this article is from GitHub here. The code we have now is much richer than the original author. But thanks to the original author.

Implementing a weather forecast app with Swift (iii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.