{"id":13635588,"url":"https://github.com/PerfectExamples/Perfect-Weather","last_synced_at":"2025-04-19T04:31:15.390Z","repository":{"id":121664432,"uuid":"69380458","full_name":"PerfectExamples/Perfect-Weather","owner":"PerfectExamples","description":"Demonstrate using URL Routes \u0026 variables, Fetching of remote data from API's as JSON, reading and transforming to data more appropriately consumable by an API client.","archived":false,"fork":false,"pushed_at":"2018-05-07T14:45:35.000Z","size":89,"stargazers_count":32,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-09T05:34:32.965Z","etag":null,"topics":["json","perfect","server-side-swift","swift","weather"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PerfectExamples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-27T17:14:03.000Z","updated_at":"2021-11-25T23:56:12.000Z","dependencies_parsed_at":"2024-08-02T00:13:01.477Z","dependency_job_id":null,"html_url":"https://github.com/PerfectExamples/Perfect-Weather","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectExamples%2FPerfect-Weather","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectExamples%2FPerfect-Weather/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectExamples%2FPerfect-Weather/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PerfectExamples%2FPerfect-Weather/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PerfectExamples","download_url":"https://codeload.github.com/PerfectExamples/Perfect-Weather/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249606300,"owners_count":21298851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","perfect","server-side-swift","swift","weather"],"created_at":"2024-08-02T00:00:47.773Z","updated_at":"2025-04-19T04:31:15.083Z","avatar_url":"https://github.com/PerfectExamples.png","language":"Swift","funding_links":[],"categories":["Samples"],"sub_categories":[],"readme":"# Perfect Weather App Example[简体中文](README.zh_CN.md)\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"http://perfect.org/get-involved.html\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://perfect.org/assets/github/perfect_github_2_0_0.jpg\" alt=\"Get Involed with Perfect!\" width=\"854\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/PerfectlySoft/Perfect\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://www.perfect.org/github/Perfect_GH_button_1_Star.jpg\" alt=\"Star Perfect On Github\" /\u003e\n    \u003c/a\u003e  \n    \u003ca href=\"http://stackoverflow.com/questions/tagged/perfect\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://www.perfect.org/github/perfect_gh_button_2_SO.jpg\" alt=\"Stack Overflow\" /\u003e\n    \u003c/a\u003e  \n    \u003ca href=\"https://twitter.com/perfectlysoft\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://www.perfect.org/github/Perfect_GH_button_3_twit.jpg\" alt=\"Follow Perfect on Twitter\" /\u003e\n    \u003c/a\u003e  \n    \u003ca href=\"http://perfect.ly\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://www.perfect.org/github/Perfect_GH_button_4_slack.jpg\" alt=\"Join the Perfect Slack\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://developer.apple.com/swift/\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Swift-3.0-orange.svg?style=flat\" alt=\"Swift 3.0\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://developer.apple.com/swift/\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Platforms-OS%20X%20%7C%20Linux%20-lightgray.svg?style=flat\" alt=\"Platforms OS X | Linux\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://perfect.org/licensing.html\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/License-Apache-lightgrey.svg?style=flat\" alt=\"License Apache\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://twitter.com/PerfectlySoft\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Twitter-@PerfectlySoft-blue.svg?style=flat\" alt=\"PerfectlySoft Twitter\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://perfect.ly\" target=\"_blank\"\u003e\n        \u003cimg src=\"http://perfect.ly/badge.svg\" alt=\"Slack Status\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nAn Example Weather App Backend for Perfect\n\nThe purpose of this example is to demonstrate using URL Routes \u0026 variables, Fetching of remote data from API's as JSON, reading and transforming to data more appropriately consumable by an API client.\n\nPackages demonstrated:\n* PerfectLib (JSON)\n* HTTPServer\n* CURL\n* [JSONConfig](https://github.com/iamjono/JSONConfig) (3rd party library for reading configurations)\n\nThis package builds with Swift Package Manager and is part of the [Perfect](https://github.com/PerfectlySoft/Perfect) project.\n\nEnsure you have installed Xcode 8.0 or later.\n\n## Obtaining an API Key\n\nThis example project requires a valid API key from [https://www.wunderground.com/weather/api/](https://www.wunderground.com/weather/api/) to function. Use this link to sign up for a developer account, and obtain an API key.\n\nThis key will be added to the `ApplicationConfiguration.json` file as described below.\n\n## Setup - Xcode 8\n\n* Check out or download the project;\n* In terminal, navigate to the directory and execute\n\n```\nswift package generate-xcodeproj\n```\n\n* Open `Perfect-Weather.xcodeproj`\n* Add to the \"Library Search Paths\" in \"Project Settings\" `$(PROJECT_DIR)`, recursive. **(This step will be unneeded in a future release of Xcode 8.)**\n* Rename the `ApplicationConfiguration.json.example` file to \t`ApplicationConfiguration.json`. \n* Open this file and change the `token` value to the WeatherUnderground token obtained above.\n* Add the file to a new \"Copy Files\" build phase as shown:\n\n![https://github.com/PerfectExamples/Perfect-Weather/raw/master/Resource/CopyFilesPhase.png](https://github.com/PerfectExamples/Perfect-Weather/raw/master/Resource/CopyFilesPhase.png)\n\n* Select the Executable build target from the build targets dropdown in Xcode\n* Run (cmd-R) to build \u0026 run in Xcode.\n\nIn Xcode's console output pane you will see:\n\n```\n[INFO] Starting HTTP server on 0.0.0.0:8181 with document root ./webroot\n```\n\n* In a browser, visit [http://localhost:8181/api/v1/current](http://localhost:8181/api/v1/current)\n\n## Setup - Terminal\n\n* Check out or download the project;\n* In terminal, navigate to the directory \n* * Rename the `ApplicationConfiguration.json.example` file to \t`ApplicationConfiguration.json`. \n* Open this file and change the `token` value to the WeatherUnderground token obtained above.\n* Execute `swift build`\n* Once the project has compiled, execute `./.build/debug/Perfect-Weather`\n\nThe output you will see:\n\n```\n[INFO] Starting HTTP server on 0.0.0.0:8181 with document root ./webroot\n```\n\n* In a browser, visit [http://localhost:8181/api/v1/current](http://localhost:8181/api/v1/current)\n\n## Included Routes\n\nThe following routes are included in this API for demonstration purposes:\n\n* GET: [http://localhost:8181/api/v1/current](http://localhost:8181/api/v1/current) - A route that returns the current weather conditions for the default location, Canada/Newmarket.\n* GET: [http://localhost:8181/api/v1/forecast](http://localhost:8181/api/v1/forecast) - A route that returns the weather forecast for the default location, Canada/Newmarket.\n* GET: [http://localhost:8181/api/v1/current/{country}/{city}](http://localhost:8181/api/v1/current/{country}/{city}) - A route that returns the current weather conditions for the specified country and city. Make sure you replace `{country}` and `{city}` with valid values.\n* GET: [http://localhost:8181/api/v1/forecast/{country}/{city}](http://localhost:8181/api/v1/forecast/{country}/{city}) - A route that returns the weather forecast for the specified country and city. Make sure you replace `{country}` and `{city}` with valid values.\n\nCurrent conditions sample response:\n\n``` javascript\n{\n  \"observation_time\": \"Last Updated on September 27, 12:00 PM ADT\",\n  \"weather\": \"Light Rain Showers\",\n  \"temperature_string\": \"54 F (12 C)\"\n}\n```\n\nForecast sample response:\n\n``` javascript\n[\n\t{\n\t\t\"icon\": \"rain\",\n\t\t\"icon_url\": \"http://icons.wxug.com/i/c/k/rain.gif\",\n\t\t\"pop\": \"100\",\n\t\t\"title\": \"Tuesday\",\n\t\t\"period\": 0,\n\t\t\"fcttext\": \"Rain likely. High 54F. Winds SE at 5 to 10 mph. Chance of rain 100%. Rainfall near a half an inch.\",\n\t\t\"fcttext_metric\": \"Rain likely. High 12C. Winds SE at 10 to 15 km/h. Chance of rain 100%. Rainfall near 12mm.\"\n\t},\n\t{\n\t\t\"icon\": \"nt_rain\",\n\t\t\"icon_url\": \"http://icons.wxug.com/i/c/k/nt_rain.gif\",\n\t\t\"pop\": \"100\",\n\t\t\"title\": \"Tuesday Night\",\n\t\t\"period\": 1,\n\t\t\"fcttext\": \"Rain early...then remaining cloudy with showers overnight. Low 48F. Winds NE at 10 to 15 mph. Chance of rain 100%. Rainfall near a quarter of an inch.\",\n\t\t\"fcttext_metric\": \"Rain early...then remaining cloudy with showers overnight. Low 9C. Winds NE at 15 to 25 km/h. Chance of rain 100%. Rainfall around 6mm.\"\n\t},\n\t{\n\t\t\"icon\": \"cloudy\",\n\t\t\"icon_url\": \"http://icons.wxug.com/i/c/k/cloudy.gif\",\n\t\t\"pop\": \"20\",\n\t\t\"title\": \"Wednesday\",\n\t\t\"period\": 2,\n\t\t\"fcttext\": \"Overcast. High 59F. Winds NNE at 10 to 15 mph.\",\n\t\t\"fcttext_metric\": \"Cloudy. High near 15C. Winds NNE at 15 to 25 km/h.\"\n\t},\n\t{\n\t\t\"icon\": \"nt_chancerain\",\n\t\t\"icon_url\": \"http://icons.wxug.com/i/c/k/nt_chancerain.gif\",\n\t\t\"pop\": \"40\",\n\t\t\"title\": \"Wednesday Night\",\n\t\t\"period\": 3,\n\t\t\"fcttext\": \"Considerable cloudiness. Occasional rain showers later at night. Low 52F. Winds NNE at 10 to 15 mph. Chance of rain 40%.\",\n\t\t\"fcttext_metric\": \"Cloudy with occasional showers late at night. Low 11C. Winds NNE at 10 to 15 km/h. Chance of rain 40%.\"\n\t},\n\t{\n\t\t\"icon\": \"cloudy\",\n\t\t\"icon_url\": \"http://icons.wxug.com/i/c/k/cloudy.gif\",\n\t\t\"pop\": \"20\",\n\t\t\"title\": \"Thursday\",\n\t\t\"period\": 4,\n\t\t\"fcttext\": \"Cloudy. High around 60F. Winds N at 10 to 20 mph.\",\n\t\t\"fcttext_metric\": \"Cloudy. High 16C. Winds N at 15 to 30 km/h.\"\n\t},\n\t{\n\t\t\"icon\": \"nt_mostlycloudy\",\n\t\t\"icon_url\": \"http://icons.wxug.com/i/c/k/nt_mostlycloudy.gif\",\n\t\t\"pop\": \"10\",\n\t\t\"title\": \"Thursday Night\",\n\t\t\"period\": 5,\n\t\t\"fcttext\": \"Mostly cloudy skies. Low around 45F. Winds N at 10 to 20 mph.\",\n\t\t\"fcttext_metric\": \"Mostly cloudy. Low 7C. Winds N at 15 to 30 km/h.\"\n\t},\n\t{\n\t\t\"icon\": \"partlycloudy\",\n\t\t\"icon_url\": \"http://icons.wxug.com/i/c/k/partlycloudy.gif\",\n\t\t\"pop\": \"20\",\n\t\t\"title\": \"Friday\",\n\t\t\"period\": 6,\n\t\t\"fcttext\": \"Intervals of clouds and sunshine. High 63F. Winds NNE at 10 to 15 mph.\",\n\t\t\"fcttext_metric\": \"Intervals of clouds and sunshine. High 17C. Winds NNE at 10 to 15 km/h.\"\n\t},\n\t{\n\t\t\"icon\": \"nt_partlycloudy\",\n\t\t\"icon_url\": \"http://icons.wxug.com/i/c/k/nt_partlycloudy.gif\",\n\t\t\"pop\": \"10\",\n\t\t\"title\": \"Friday Night\",\n\t\t\"period\": 7,\n\t\t\"fcttext\": \"Partly cloudy skies. Low 47F. Winds NNE at 5 to 10 mph.\",\n\t\t\"fcttext_metric\": \"A few clouds. Low 8C. Winds NNE at 10 to 15 km/h.\"\n\t}\n]\n```\n\n## Postman Collection\n\nThe repo includes a file `Example-WeatherAPI.postman_collection` which is a Postman URL collection.\n\nWith Postman installed, import and use to easily query the routes.\n\n## Further Information\nFor more information on the Perfect project, please visit [perfect.org](http://perfect.org).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPerfectExamples%2FPerfect-Weather","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPerfectExamples%2FPerfect-Weather","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPerfectExamples%2FPerfect-Weather/lists"}