DevMountain/Weather

语言: Swift

git: https://github.com/DevMountain/Weather

一个Swift,iOS应用程序,用于在用户请求的城市中获取当前天气以练习异步网络请求,工作......
A Swift, iOS app to get the current weather in a user-requested city to practice asyncronous network requests, workin…
README.md (中文)

天气

2级

学生将构建一个应用程序,以便在用户请求的城市中获取当前天气,以练习异步网络请求,使用JSON数据和闭包。

独立完成此项目的学生可以:

  • 使用NSURLSession进行不同的网络调用
  • 解析JSON数据并从数据生成模型对象
  • 在异步任务完成时使用闭包来执行代码

故事板

设置场景以允许用户搜索城市,然后查看他们的天气搜索结果。

  1. 使用OpenWeatherMap上的API文档,确定可以从API获取哪些信息。对于对当前天气感兴趣的人,哪些信息可能有用?您如何允许用户搜索城市?邮政编码?城市名?纬度/经度?转到示例端点,看看您将获得什么JSON。
  2. 使用(1)中的信息,构建单个视图。它应该有一个搜索栏(UITextField),用于显示信息的标签和一个图像视图(Black Diamond)。
  3. 为此场景添加一个名为WeatherViewController.swift的类文件,并在Storyboard中指定场景。

实施模型

创建一个Weather模型类,它将保存要显示给用户的信息

  1. 创建Weather.swift类文件并定义新的Weather类
  2. 添加main,description,iconString,iconImage:UIImage的属性? (黑钻石),温度K:漂浮?,城市名称,温度C:漂浮?
  3. 为main,description,iconString和cityName提供初始值
  4. 使温度C成为计算变量,从温度K计算它的值。
  5. 使用示例端点,创建initWithJSON方法。这将采用一个参数,一个字典,并创建一个初始化的天气对象。这将解析字典以设置新Weather对象的属性。

网络控制器

创建一个NetworkController类。这将有方法来构建您可能需要的不同URL,并且它应该有一个从URL返回NSData的方法。

  1. NetworkController应该有一些代表您的API密钥和baseURL的静态常量。
  2. 编写一个将接受搜索词的函数(解决方案代码使用城市名称)并返回NSURL端点,记住在需要时转义搜索词。
  3. 编写一个将采用NSURL和完成闭包的函数(dataAtURL:completion :)。完成闭包的参数应该是NSData类型?并且闭包应该返回Void。此方法将进行网络调用,如果成功,将使用来自网络调用的NSData调用完成闭包作为其参数。如果不成功,仍应调用完成闭包,但nil应该是参数。
  4. 此时,您应该测试网络控制器方法dataAtURL以查看是否正在返回数据。

从iOS 9开始,Apple正在提高安全性并试图要求开发人员使用https。对于此API,您必须拥有付费API帐户才能使用https。为了这个应用程序和学习,我们将关闭此安全功能。该错误消息应描述有关阻止明文HTTP的App Transport Security的问题。 Apple要求的解决方法是在Info.plist中添加键值对。此键值对应为:App Transport Security Settings:[允许任意加载:是]。

气象控制器

创建一个WeatherController类。这将具有视图控制器调用的方法,以通过完成闭包来“返回”天气数据。

  1. WeatherController上应该有一个方法,允许开发人员传入搜索参数,并通过完成闭包提供Weather对象。 此方法应使用NetworkController来获取NSURL。 此方法应调用NetworkController的dataAtURL方法以在上一个项目符号点中创建的URL处获取NSData。 在dataAtURL的关闭中检查以确保实际获得NSData,而不是nil值。如果为nil,请将此方法称为完成,使用nil作为天气的值?参数,否则继续。 尝试(< - * Hint,Hint)将NSData序列化为JSON对象。如果我们捕获一个例外,用nil作为天气调用完成闭包?参数。如果可以序列化NSData,则创建一个Weather对象并使用新创建的Weather对象调用完成闭包。

WeatherViewContoller的代码

实现WeatherViewController类。连接视图,添加执行搜索和更新视图的方法。

  1. 将Storyboard中的视图连接到视图控制器中的IBOutlets。
  2. 符合UISearchBarDelegate。你能找到用户想要搜索时要调用的方法吗? searchBarSearchButtonClicked怎么样:
  3. 实现上面步骤(2)中找到的委托方法。你应该调用你的WeatherController的搜索方法。在完成闭包中,您应该将Weather对象作为参数(除非出现问题,在这种情况下,Weather?对象将为nil)。使用此Weather对象和Grand Central Dispatch,更新相应的视图。

黑钻石

  • 序列化Weather对象后,您可能已经注意到iconString有一个键值对。使用此iconString获取表示当前天气状况的图像。在NetworkController中使用API​​文档,一种新方法(您需要编写),它将为图标提供NSURL,这是WeatherController中的一个新方法,它将在完成闭包中为您提供图像。
  • 允许用户以与您最初实现的方式不同的方式进行搜索。例如,如果您允许用户按城市搜索,请让他们通过zip(或发布)代码进行搜索。
  • 如果没有“返回天气”,则通知用户搜索失败。

捐款

请参阅CONTRIBUTING.md。

版权

©DevMountain LLC,2015。未经DevMountain,LLC明确书面许可,严禁未经授权使用和/或复制本资料。可以使用摘录和链接,前提是向DevMountain提供完整和明确的信用,并对原始内容进行适当且具体的指导。

本文使用googletrans自动翻译,仅供参考, 原文来自github.com

en_README.md

Weather

Level 2

Students will build an app to get the current weather in a user-requested city to practice asyncronous network requests, working with JSON data, and closures.

Students who complete this project independently are able to:

  • use NSURLSession to make aysncronous network calls
  • parse JSON data and generate model object from the data
  • use closures to execute code when an asyncronous task is complete

Storyboard

Set up a scene to allow the user to search for a city and then see the results of their weather search.

  1. Using the documentation of the API at OpenWeatherMap, determine what information you can get from the API. What information might be useful for someone interested in the current weather? How are you going to allow the user to search for a city? Zip Code? City Name? Latitude/Longitude? Go to a sample endpoint and see what JSON you will get back.
  2. Using this information from (1), build out the single view. It should have a search bar (UITextField), labels to display the information, and an image view (Black Diamond).
  3. Add a class file for this scene called WeatherViewController.swift and assign the scene in the Storyboard.

Implement Model

Create a Weather model class that will hold the information to display to the user

  1. Create a Weather.swift class file and define a new Weather class
  2. Add properties for main, description, iconString, iconImage: UIImage? (Black Diamond), temperatureK: Float?, cityName, temperatureC: Float?
  3. Give initial values to main, description, iconString, and cityName
  4. Make temperatureC be a computed variable that computes it's value from temperatureK.
  5. Using a sample endpoint, create an initWithJSON method. This will take one parameter, a dictionary, and create an initialized weather object. This will parse through the dictionary to set the Properties of a new Weather object.

Network Controller

Create a NetworkController class. This will have methods to build the different URLs you might want and it should have a method to return NSData from a URL.

  1. The NetworkController should have some static constant that represents your API key and your baseURL.
  2. Write a function that will take in a search term (the solution code uses a city name) and return an NSURL endpoint, remember to escape the search term if needed.
  3. Write a function that will take an NSURL and a completion closure (dataAtURL:completion:). The parameter of the completion closure should be of type NSData? and the closure should return Void. This method will make the network call and if successful will call the completion closure with the NSData from the network call as it's parameter. If it is unsuccessful, the completion closure should still be called, but nil should be the parameter.
  4. At this point you should be testing your network controller method dataAtURL to see if you are getting data returned.

As of iOS 9, Apple is boosting security and trying to require developers to use https. For this API, you must have a paid API account to use https. For the sake of this app and learning, we will turn off this security feature. The error message should describe the issue about App Transport Security blocking a cleartext HTTP. A workaround to Apple's requirements is to add a key-value pair to your Info.plist. This key-value pair should be: App Transport Security Settings : [Allow Arbitrary Loads : YES].

Weather Controller

Create a WeatherController class. This will have methods that are called by the view controller to "return" the weather data through completion closures.

  1. The WeatherController should have a method on it that allows the developer to pass in the search parameter and, through a completion closure, provide a Weather object.
    • This method should use the NetworkController to get the NSURL.
    • This method should call the NetworkController's dataAtURL method to get the NSData at the URL created in the previous bullet point.
    • In the closure of the dataAtURL check to make sure you actually get NSData back, not a nil value. If nil, call this methods completion with nil as the value for the Weather? parameter, else continue.
    • try (<- *Hint, Hint) to serialize the NSData to JSON objects. If we catch an exeception, call the completion closure with nil as the Weather? parameter. If the NSData can be serialized, create a Weather object and call the completion closure with the newly created Weather object.

Code for WeatherViewContoller

Implement the WeatherViewController class. Wire up the views, add methods to perform the search and update the views.

  1. Wire up the views in Storyboard to the IBOutlets in the view controller.
  2. Conform to the UISearchBarDelegate. Can you find the method that is going to be called when the user wants to search?
    • How about searchBarSearchButtonClicked:
  3. Implement the delegate method found in step (2) above. You should call your WeatherController's search method. In the completion closure, you should have the Weather object as a parameter (unless something went wrong, in which case the Weather? object will be nil). Using this Weather object and Grand Central Dispatch, update the appropriate views.

Black Diamonds

  • After serializing the Weather object, you should may have noticed that there is a key-value pair for an iconString. Use this iconString to get an image representing the current weather conditions. Use the API documentation, a new method (which you will need to write) in the NetworkController that will provide the NSURL for the icon, a new method in WeatherController that will provide you an image in the completion closure.
  • Allow the user to search in a different way than you initially implemented above. For example if you allowed the user to search by city, let them search by zip (or post) code.
  • If no Weather was "returned," notify the user that a search failed.

Contributions

Please refer to CONTRIBUTING.md.

Copyright

© DevMountain LLC, 2015. Unauthorized use and/or duplication of this material without express and written permission from DevMountain, LLC is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to DevMountain with appropriate and specific direction to the original content.