I have this app that I made with Swift, for fun and because I'm a beginner. Basically what it does is you can enter an artist name and song name and it fetches lyrics from AZLyrics.com based on the artist and song name you entered. For some reason most of the time when I try and load lyrics the first time when I open the app it doesn't load (it loads the 2nd, 3rd, 4th etc time). Here is my code could someone please tell me how I could fix this?
First View controller
import UIKit
var lyricsWithQuotes = ""
var urlError = false
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet var songName: UITextField!
#IBOutlet var artistName: UITextField!
#IBAction func search(sender: AnyObject) {
var url = NSURL(string: "http://www.azlyrics.com/lyrics/" + artistName.text.stringByReplacingOccurrencesOfString(" ", withString: "").stringByReplacingOccurrencesOfString("'", withString: "").stringByReplacingOccurrencesOfString(",", withString: "").stringByReplacingOccurrencesOfString(".", withString: "").lowercaseString + "/" + songName.text.stringByReplacingOccurrencesOfString(" ", withString: "").stringByReplacingOccurrencesOfString("'", withString: "").stringByReplacingOccurrencesOfString(",", withString: "").stringByReplacingOccurrencesOfString(".", withString: "").lowercaseString + ".html")
if url != nil {
let task = NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data, response, error) -> Void in
if error == nil {
var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding) as NSString!
var urlContentArray = urlContent.componentsSeparatedByString("<!-- Usage of azlyrics.com content by any third-party lyrics provider is prohibited by our licensing agreement. Sorry about that. -->")
if urlContent.containsString("It's a place where all searches end!") {
urlError = true
} else {
var lyricsArray = urlContentArray[1].componentsSeparatedByString("<br><br>")
var lyrics = lyricsArray[0] as! String
var lyricsWithoutBR = lyrics.stringByReplacingOccurrencesOfString("<br>", withString: "")
var lyricsWithoutSlashDiv = lyricsWithoutBR.stringByReplacingOccurrencesOfString("</div>", withString: "")
var lyricsWithoutI = lyricsWithoutSlashDiv.stringByReplacingOccurrencesOfString("<i>", withString: "")
var lyricsWithoutSlashI = lyricsWithoutI.stringByReplacingOccurrencesOfString("</i>", withString: "")
lyricsWithQuotes = lyricsWithoutSlashI.stringByReplacingOccurrencesOfString(""", withString: "\"")
}
} else {
urlError = true
}
})
task.resume()
} else {
urlError = true
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
view.endEditing(true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
override func viewDidLoad() {
super.viewDidLoad()
artistName.delegate = self
songName.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Second View Controller
import UIKit
var lyricsComplete = ""
class ViewController2: UIViewController {
#IBOutlet var lyricsDisplay: UITextView!
override func viewDidAppear(animated: Bool) {
if urlError == true {
urlError = false
lyricsDisplay.text = "Couldn't find that song!"
} else {
lyricsComplete = lyricsWithQuotes
lyricsDisplay.text = lyricsComplete
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
After your NSURLSession has completed - basically this line:
lyricsWithQuotes = lyricsWithoutSlashI.stringByReplacingOccurrencesOfString(""", withString: "\"")
You have two options:
Option One - Programatically launch the view:
let storyboard = UIStoryboard(name: "STORYBOARD NAME HERE", bundle: nil)
let newVC = storyboard.instantiateViewControllerWithIdentifier("VIEW CONTROLLER IDENTIFIER HERE") as! ViewController2
newVC.lyricsComplete = lyricsWithQuotes
If you have a navigation controller:
self.navigationController?.pushViewController(newVC, animated: true)
If you don't have a navigation controller:
self.showViewController(newVC, sender: self)
Options 2 - Trigger the Segue:
performSegueWithIdentifier("SEGUE NAME HERE", sender: nil)
Then intercept the Segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if(segue.identifier == "SEGUE NAME HERE"){
let newVC = segue.destinationViewController as! ViewController2
newVC.lyricsComplete = lyricsWithQuotes
}
}
If you use option 2, make sure the Segue is between the View Controllers and not attached to your button:
Like this:
Not like this:
Related
I am trying to get my app to call to an API, retrieve information about a movie based on a user search, and then pass that data to the next view using segue. Everything seems to be working fine up until the point where the data is supposed to be getting transferred over. My two view controllers and the file where i call my API are below.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var searchBar: UISearchBar!
var movieManager = MovieManager()
var movieTitle = ""
var movieDescription = ""
var results: [Results] = []
override func viewDidLoad() {
movieManager.delegate = self
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
//MARK: - Movie Manager Methods
extension ViewController: MovieManagerDelegate {
func didUpdateMovie(title: String?, description: String?, resultsList: [Results]?) {
movieTitle = title!
movieDescription = description!
results = resultsList!
print("\(movieTitle) \n \(movieDescription)")
}
func didFailWithError(error: Error) {
print("error")
}
}
//MARK: - Search Bar Methods
extension ViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
movieManager.searchMovie(for: searchBar.text!)
searchBar.text = ""
searchBar.resignFirstResponder()
performSegue(withIdentifier: "goToResults", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToResults" {
if let destinationVC = segue.destination as? ResultsListViewController {
destinationVC.movieTitle = self.movieTitle
}
}
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
searchBar.resignFirstResponder()
return true
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
}
import UIKit
class ResultsListViewController: UIViewController {
#IBOutlet weak var movieName: UILabel!
var movieTitle: String = ""
override func viewDidLoad() {
super.viewDidLoad()
movieName.text = movieTitle
}
}import UIKit
class ResultsListViewController: UIViewController {
#IBOutlet weak var movieName: UILabel!
var movieTitle: String = ""
override func viewDidLoad() {
super.viewDidLoad()
movieName.text = movieTitle
}
}
import Foundation
protocol MovieManagerDelegate {
func didUpdateMovie(title: String?, description: String?, resultsList: [Results]?)
func didFailWithError(error: Error)
}
struct MovieManager {
var movieTitle: String?
var movieDescription: String?
var results: [Results]?
var delegate: MovieManagerDelegate?
let baseURL = "https://imdb-api.com/en/API/SearchMovie/(APIKEYHERE)/"
func searchMovie(for userSearch: String){
let urlString = "\(baseURL)\(userSearch)"
if let url = URL(string: urlString){
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { data, response, error in
if error != nil {
self.delegate?.didFailWithError(error: error!)
return
}
if let safeData = data {
let movieInfo = self.parseJSON(safeData)
self.delegate?.didUpdateMovie(title: movieInfo.0!, description: movieInfo.1!, resultsList: movieInfo.2)
}
}
task.resume()
}
}
func parseJSON(_ data: Data) -> (String?, String?, [Results]) {
let decoder = JSONDecoder()
var movieTitle = "", movieDescription = "", searchResults: [Results] = []
do {
if let decodedData = try decoder.decode(MovieData?.self, from: data) {
movieTitle = decodedData.results.first!.title
movieDescription = decodedData.results.first!.description
searchResults = decodedData.results
// print("\(movieTitle) \n \(movieDescription)")
}
return (movieTitle, movieDescription, searchResults)
} catch {
print(error)
}
return (movieTitle, movieDescription, searchResults)
}
}
Problem is Segue to next controller before the result of API.
Try to Segue after API result
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
movieManager.searchMovie(for: searchBar.text!)
searchBar.text = ""
searchBar.resignFirstResponder()
//Segue to next controller before the result of API
performSegue(withIdentifier: "goToResults", sender: self)
}
So your segue to next controller would be after result of parseJSON or didUpdate delegate
I created a UITextField where, when the user writes a link and enters, my textfield disappears and my webView appears.
What I am trying to do is, when the user writes the first time their link, the textfield saves that link and when the user opens again the app, the web view opens directly from the last link that the user wrote in the textfield. Basically the stored link should run the second time.
Here is all my code:
import UIKit
import Foundation
let urlKey = "User URL"
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
self.webView.hidden = true
self.textField.addTarget(self, action: #selector(ViewController.textFieldDidUpdate(_:)), forControlEvents: UIControlEvents.EditingChanged)
if doesURLExist() {
self.textField.text = getURL()
}
}
// Text Field Delegate
func textFieldDidUpdate(textField: UITextField)
{
// Remove Spaces
textField.text = textField.text!.stringByReplacingOccurrencesOfString(" ", withString: "", options: [], range: nil)
// Validate URL
NSURL.validateUrl(textField.text, completion: { (success, urlString, error) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if (success)
{
self.saveURL(urlString!)
self.webView.hidden = false
self.textField.hidden = true
let request = NSURLRequest(URL: NSURL(string: urlString!)!)
self.webView.loadRequest(request)
}
else
{
self.webView.stopLoading()
self.webView.hidden = true
}
})
})
}
#IBAction func dismissKeyboard(sender: AnyObject) {
self.resignFirstResponder()
self.view.endEditing(true)
}
func saveURL(urlString: String) {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(urlString, forKey: urlKey)
}
func getURL() -> String {
let defaults = NSUserDefaults.standardUserDefaults()
let urlString = defaults.objectForKey(urlKey) as! String
return urlString
}
func doesURLExist() -> Bool {
let defaults = NSUserDefaults.standardUserDefaults()
guard let _ = defaults.objectForKey(urlKey) where defaults.objectForKey(urlKey) is String else {
return false
}
return true
}
}
Here is my project in GitHub: https://github.com/anappleapp/NSURLvalidation
You'll want to check if the url exists first by calling doesURLExist, if it does, you opt out of presenting that textfield. If it does not exist, call saveURL. NSUserDefaults provides a simple means to store lightweight data.
let urlKey = "User URL"
func saveURL(urlString: String) {
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(urlString, forKey: urlKey)
}
func getURL() -> String {
let defaults = NSUserDefaults.standardUserDefaults()
let urlString = defaults.objectForKey(urlKey) as! String
return urlString
}
func doesURLExist() -> Bool {
let defaults = NSUserDefaults.standardUserDefaults()
guard let _ = defaults.objectForKey(urlKey) where defaults.objectForKey(urlKey) is String else {
return false
}
return true
}
So your class should look something like:
import UIKit
import Foundation
let urlKey = "User URL"
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
self.webView.hidden = true
self.textField.addTarget(self, action: #selector(ViewController.textFieldDidUpdate(_:)), forControlEvents: UIControlEvents.EditingChanged)
if(doesURLExist) {
self.textField.text = getURL()
}
// Demo UI Settings
}
}
// Text Field Delegate
func textFieldDidUpdate(textField: UITextField)
{
// Remove Spaces
textField.text = textField.text!.stringByReplacingOccurrencesOfString(" ", withString: "", options: [], range: nil)
// Validate URL
NSURL.validateUrl(textField.text, completion: { (success, urlString, error) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if (success) {
self.saveURL(urlString)
self.webView.hidden = false
self.textField.hidden = true
let request = NSURLRequest(URL: NSURL(string: urlString!)!)
self.webView.loadRequest(request)
} else {
self.webView.stopLoading()
self.webView.hidden = true
}
})
})
}
Don't forget to add the original functions to your class.
You should save the entered string to user defaults. When your app opens you should check user defaults to see if there's already a saved string.
Swift 2 code to save your URL to user defaults:
NSUserDefaults.standardUserDefaults().setObject(urlString!, forKey: "EnteredURLString")
Swift 2 code to check whether there's a saved URL string:
if let urlString = NSUserDefaults.standardUserDefaults().stringForKey("EnteredURLString") {
}
I try to pass data from my ViewController to TableViewPlace.swiftUse the buttons. When I am choosing button return not some thing
viViewController
class ViewController: UIViewController {
struct Country{
var id :Int
init(id:Int){
self.id = id
}
}
var CountrySelected = [Country]()
var countryArry = NSArray()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func airAction(sender: AnyObject) {
}
#IBAction func viewPlaceAction(sender: AnyObject) {
getParsePlaceView()
// json viewPlace
performSegueWithIdentifier("viewPlaceSegu", sender: sender)
}
#IBAction func tourAction(sender: AnyObject) {
}
/// Open the page
// parse json
func getParsePlaceView(){
let url = NSURL(string: "http://jsonplaceholder.typicode.com/posts")
NSURLSession.sharedSession().dataTaskWithURL(url!){ [unowned self] (data , repsonse , error) in
if error != nil {
print(error!)
} else {
do {
let posts = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers) as! [[String:AnyObject]]
for post in posts {
if let id = post["userId"] as? Int{
// print(id)
let sets = Country(id: id)
self.CountrySelected.append(sets)
}
}
self.countryArry = posts
print(self.countryArry)// return data and currect
} catch let error as NSError {
print(error)
}
}
}.resume()
print(countryArry) // return nil why??
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// get a reference to the second view controller
if segue.identifier == "viewPlaceSegu" {
if let secondViewController = segue.destinationViewController as? TableViewPlace {
// set a variable in the second view controller with the String to pass
print(countryArry)
secondViewController.tnt = countryArry
}
}
}
}
when I print(countryArry) return nil why ??
Can someone help me or give me a better solution?
You are creating a Post object with this line :
let countryPlace = Post(userid: post["userId"] as! Int, title: post["title"] as! String)
And you are trying to pass to your tableview this Post object to your tnt variable which is a ViewController class, this is why you've got the first error :
secondViewController.tnt = Country
Then, if you want to add your string country to your mutable array you have to do :
if let title = tnt.title {
Country.append(title)
}
I am attempting to send an array of data to a new view controller and I'm currently getting the error fatal error: unexpectedly found nil while unwrapping an Optional value
Im using the API data from www.thecocktaildb.com
Example:
http://www.thecocktaildb.com/api/json/v1/1/search.php?s=margarita
Not sure what I'm doing wrong. Tried debugging and checking values before the segue in my search view controller and they're accurate.
Heres my code:
Main Storyboard
SearchViewController
class SearchViewController: UIViewController, UISearchBarDelegate, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var TableView: UITableView!
#IBOutlet weak var SearchBar: UISearchBar!
var valueToPass:Drinks!
var isSearching : Bool = false
class Drinks {
var idDrink: Int = 0
var strDrink: String = ""
var strCategory: String = ""
var strAlcoholic: String = ""
var strGlass: String = ""
var strInstructions: String = ""
var strDrinkThumb: String = ""
var strIngredient1: String = ""
var strIngredient2: String = ""
var strIngredient3: String = ""
var strIngredient4: String = ""
var strIngredient5: String = ""
var strIngredient6: String = ""
var strIngredient7: String = ""
var strIngredient8: String = ""
var strIngredient9: String = ""
var strIngredient10: String = ""
var strIngredient11: String = ""
var strIngredient12: String = ""
var strIngredient13: String = ""
var strIngredient14: String = ""
var strIngredient15: String = ""
var strMeasure1: String = ""
var strMeasure2: String = ""
var strMeasure3: String = ""
var strMeasure4: String = ""
var strMeasure5: String = ""
var strMeasure6: String = ""
var strMeasure7: String = ""
var strMeasure8: String = ""
var strMeasure9: String = ""
var strMeasure10: String = ""
var strMeasure11: String = ""
var strMeasure12: String = ""
var strMeasure13: String = ""
var strMeasure14: String = ""
var strMeasure15: String = ""
}
var TableData:Array< Drinks > = Array < Drinks >()
override func viewDidLoad() {
super.viewDidLoad()
for subView in self.SearchBar.subviews
{
for subsubView in subView.subviews
{
if let textField = subsubView as? UITextField
{
textField.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("Search", comment: ""))
}
}
}
self.SearchBar.delegate = self
self.TableView.delegate = self
self.TableView.dataSource = self
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if self.SearchBar.text!.isEmpty {
self.isSearching = false
}else{
self.isSearching = true
let userSearchInput = self.SearchBar.text!.lowercaseString
let newString = userSearchInput.stringByReplacingOccurrencesOfString(" ", withString: "%20", options: NSStringCompareOptions.LiteralSearch, range: nil)
let postEndpoint: String = "http://www.thecocktaildb.com/api/json/v1/1/search.php?s=" + newString
guard let url = NSURL(string: postEndpoint) else {
print("Error: cannot create URL")
return
}
let urlRequest = NSURLRequest(URL: url)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let task = session.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, error) in
guard let responseData = data else {
print("Error: did not receive data")
return
}
guard error == nil else {
print("error calling GET on www.thecocktaildb.com")
print(error)
return
}
let post: NSDictionary
do {
post = try NSJSONSerialization.JSONObjectWithData(responseData,
options: []) as! NSDictionary
} catch {
print("error trying to convert data to JSON")
return
}
var count = 1
if let drinks = post["drinks"] as? [NSDictionary] {
self.TableData.removeAll()
for drink in drinks {
let adrink = Drinks()
if let strDrink = drink["strDrink"] as? String {
print(String(count) + ". " + strDrink)
adrink.strDrink = strDrink
count++
}
if let strCategory = drink["strCategory"] as? String {
print(" Category: " + strCategory)
adrink.strCategory = strCategory
}
if let strDrinkThumb = drink["strDrinkThumb"] as? String {
print(" Thumbnail Image: " + strDrinkThumb)
adrink.strDrinkThumb = strDrinkThumb
}
self.TableData.append(adrink)
self.TableView.reloadData()
}
}
})
task.resume()
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TableData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
//title = TableData[indexPath.row].strDrink
cell.textLabel?.text = TableData[indexPath.row].strDrink;
let imageString = TableData[indexPath.row].strDrinkThumb
if (imageString == ""){
let noDrinkImage : UIImage = UIImage(named: "noimage.jpg")!
cell.imageView!.image = noDrinkImage
}else{
let drinkImage = UIImage(data: NSData(contentsOfURL: NSURL(string:TableData[indexPath.row].strDrinkThumb)!)!)
cell.imageView!.image = drinkImage
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
print(TableData[indexPath.row].strDrink)
valueToPass = TableData[indexPath.row]
//self.performSegueWithIdentifier("drinkSegue", sender: TableData[indexPath.row])
}
// hide kwyboard when search button clicked
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
self.SearchBar.resignFirstResponder()
}
// hide keyboard when cancel button clicked
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
self.SearchBar.text = ""
self.SearchBar.resignFirstResponder()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "DrinkSegue") {
// initialize new view controller and cast it as your view controller
let drinkViewController = segue.destinationViewController as! DrinkViewController
// your new view controller should have property that will store passed value
drinkViewController.passedValue = valueToPass
}
}
}
DrinkViewController.swift
class DrinkViewController: UIViewController {
#IBOutlet weak var DrinkNameLabel: UILabel!
var passedValue : SearchViewController.Drinks!
override func viewDidLoad() {
super.viewDidLoad()
DrinkNameLabel.text = passedValue!.strDrink
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Do it like this instead
In your didSelectRowAtIndexPath pass the array
self.performSegueWithIdentifier("drinkSegue", sender: TableData[indexPath.row])
Here you need to pass the array to your DrinkViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "DrinkSegue") {
// initialize new view controller and cast it as your view controller
let drinkViewController = segue.destinationViewController as! DrinkViewController
// your new view controller should have property that will store passed value
drinkViewController.passedValue = valueToPass
// declare myArray in your drinkViewController and then assign it here
// now your array that you passed will be available through myArray
drinkViewController.myArray = sender
}
}
Update
After I got your project I noticed that the issue you had was that you did drag a segue from the tableView to the drinksController directly - what happened is that didSelectRowAtIndexPath will not be called and your sender will always be nil drinkViewController.myArray = sender as! Drinks.
I changed that by dragging the segue from the viewController to the drinksController instead.
I want to randomize the image background of weather depending on the weather information. I want to make them work one after the other;
the first function will make a string and the second function use the string produced by the first one.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var cityNameTextField: UITextField!
#IBOutlet weak var weatherFact: UILabel!
#IBOutlet weak var weatherImage: UIImageView!
var weather = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.cityNameTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func weatherButton(sender: UIButton) {
weatherInformation()
randomWeatherImage()
}
func showError() {
self.weatherFact.text = "we can't load the weather of \(cityNameTextField.text). please try again"
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
self.view.endEditing(true)
return true
}
func randomWeatherImage() {
if weatherFact.text != nil {
let string = weather
let regex = NSRegularExpression(pattern: "-?[0-9]{1,3}", options: NSRegularExpressionOptions(), error: nil)
if let matches = regex?.matchesInString(string, options: NSMatchingOptions(), range: NSRange(location: 0, length: count(string))){
let degrees = matches.map { return(string as NSString).substringWithRange($0.range) }
var maxDegree = degrees[0].toInt()
var minDegree = degrees[1].toInt()
var averageWeather:Int = (maxDegree! + minDegree!) / 2
if averageWeather < 0 {
self.weatherImage.image = UIImage(named: "Cold.jpg")
}
else if averageWeather > 20 {
self.weatherImage.image = UIImage(named: "Warm.jpg")
}
else {
self.weatherImage.image = UIImage(named: "Mild.jpg")
}
}
}
}
func weatherInformation() {
let url = NSURL(string: "http://www.weather-forecast.com/locations/" + cityNameTextField.text.stringByReplacingOccurrencesOfString(" ", withString: "-") + "/forecasts/latest")
if url != nil {
let task = NSURLSession.sharedSession().dataTaskWithURL(url!){ (data, response, error) in
var urlError = false
if error == nil {
var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding)
var urlContentArray = urlContent!.componentsSeparatedByString("<span class=\"phrase\">")
if urlContentArray.count > 0 {
var weatherArray = urlContentArray[1].componentsSeparatedByString("</span>")
self.weather = weatherArray[0] as! String
self.weather = self.weather.stringByReplacingOccurrencesOfString("°", withString: "º")
}
else {
urlError = true
}
}
else {
urlError = true
}
dispatch_async(dispatch_get_main_queue()) {
if urlError == true {
self.showError()
}
else {
self.weatherFact.text = self.weather
}
}
}
task.resume()
}
else {
showError()
}
}
}
Just call randomWeatherImage after you set weatherFact.text:
dispatch_async(dispatch_get_main_queue()) {
if urlError == true {
self.showError()
}
else {
self.weatherFact.text = self.weather
self.randomWeatherImage()
}
}