Pr0tonion
Pr0tonion

Reputation: 207

Passing data from a class to same instance of a viewcontroller

When a specific event happens(in my case when a tab bar is changed) I want to create a new link from an Array. I have gotten this to work but the problem I am not facing is when i try to pass the generated link to the same viewcontroller i get an error

fatal error: unexpectedly found nil while unwrapping an Optional value

This happens when I try to change the UILabel movietitle and imageview. I think this is because every time it sends the link it creates a new ViewController instead of using the existing one. Might also be that i have missed an unwrapped value somewhere. Hope someone here can help me!

StringBuilder:

import UIKit

class StringBuilder: NSObject {

let urlString = "https://api.themoviedb.org/3/discover/movie?api_key=935f539acb9e5534ddeed3fb57e&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres=12"

let urlStringMultipleGenres = "https://api.themoviedb.org/3/discover/movie?api_key=935f539acbf5534ddeed3fb57e&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres=28,12,10749"
var currentGenreArray: Array<Int> = []






//This will be run after the user has selected or deselected genres in the genreControllerView
func updateGenres(genreArrayIn: Array<Int>){
    print("update genres input: ")
    print(genreArrayIn)

    //If new array input is the same as old arrayinput, do nothing
    if genreArrayIn == currentGenreArray{
        return
    }
    else{
        let returnedLink = generateString(genreID: genreArrayIn)
        print("Returned link after generate string" + returnedLink)
        sendLink(link: returnedLink)
    }


}
//After the updated genres have been put into an Array, this function will generate the whole string which
//will be the main String the getMovieRequest follows
func generateString(genreID: Array<Int>) -> String{

    let filteredGenreArray = filterZeroes(unfilteredArray: genreID)

    currentGenreArray = genreID
    print("current genre array: ")
    print(currentGenreArray)

    let baseString = "https://api.themoviedb.org/3/discover/movie?api_key=935f539acbfed4ddeed3fb57e&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres="
    var generatedString = baseString

    for id in filteredGenreArray{
        let k = String(id)
        generatedString += k + ","
    }
    print("Generated Link from Strinbuilder: ")
    print(generatedString)


    return generatedString
}
func filterZeroes(unfilteredArray: Array<Int>) -> Array<Int>{

    let filteredGenreArray = unfilteredArray.filter {$0 > 0}
    print("filtered array: ")
    print(filteredGenreArray)
    return filteredGenreArray
}


func sendLink(link: String){
    let storyBoard = UIStoryboard(name: "Main", bundle: nil)
    let movieVC = storyBoard.instantiateViewController(withIdentifier: "movieView") as! ViewController

    movieVC.getMovieData(activeGenreLink: link)
    print("new link sent from sendlink()")
}

}

ViewController:

import UIKit
import Alamofire
import AlamofireImage





class ViewController: UIViewController{

static let sharedInstance = ViewController()

var movieIndex = 0
var movieArray:[Movie] = []
var downloadGrp = DispatchGroup()




@IBOutlet var uiMovieTitle: UILabel!

@IBOutlet var uiMoviePoster: UIImageView!

@IBOutlet var posterLoading: UIActivityIndicatorView!



override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let firstTimeLink = "https://api.themoviedb.org/3/discover/movie?api_key=935f539acb9e5534ddeed3fb57e&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres=35,18"

    getMovieData(activeGenreLink: firstTimeLink)

    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    uiMoviePoster.isUserInteractionEnabled = true
    uiMoviePoster.addGestureRecognizer(tapGestureRecognizer)
    print("settings Sucessful")
}


func imageTapped(tapGestureRecognizer: UITapGestureRecognizer){





     performSegue(withIdentifier: "detailsSegue", sender: self)
    }



@IBAction func yesBtn(_ sender: UIButton) {
    movieIndex += 1
    updateUI()
}

@IBAction func seenBtn(_ sender: UIButton) {
    movieIndex += 1
}

@IBAction func noBtn(_ sender: UIButton) {
    movieIndex += 1
}




//Get movie data

func getMovieData(activeGenreLink: String){

    //self.posterLoading.startAnimating()

    movieIndex = 0
    self.downloadGrp.enter()
        Alamofire.request(activeGenreLink).responseJSON { response in
            //print(response.request)  // original URL request
            //print(response.response) // HTTP URL response
            //print(response.data)     // server data
            //print(response.result)   // result of response serialization

            self.movieArray = []

            print(self.movieArray)
            if let json = response.result.value as? Dictionary<String,AnyObject> {
                if let movies = json["results"] as? [AnyObject]{
                    for movie in movies{
                        let movieObject: Movie = Movie()

                        let title = movie["title"] as! String
                        let releaseDate = movie["release_date"] as! String
                        let posterPath = movie["poster_path"] as! String
                        let overView = movie["overview"] as! String
                        let movieId = movie["id"] as! Int
                        let genre_ids = movie["genre_ids"] as! [AnyObject]

                        movieObject.title = title
                        movieObject.movieRelease = releaseDate
                        movieObject.posterPath = posterPath
                        movieObject.overView = overView
                        movieObject.movieId = movieId


                        for genre in genre_ids{//Genre ids, fix this
                            movieObject.movieGenre.append(genre as! Int)
                        }

                        Alamofire.request("http://image.tmdb.org/t/p/w1920" + posterPath).responseImage {
                            response in
                            //print(response.request)
                            //print(response.response)
                            //debugPrint(response.result)

                            if var image = response.result.value {
                                image = UIImage(data: response.data!)!

                                movieObject.poster = image
                            }
                        }

                        self.movieArray.append(movieObject)


                    }//End of for each movie
                }
                else{
                    print("error while making results anyobject")
                }
            }
            else{
            print("error while trying to make NSDictionary")}
     self.downloadGrp.leave()
    }//End of Json request


    downloadGrp.notify( queue: .main){
        print("all downloads finished")


        DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
            print(self.movieArray[0].title!)
            self.updateUI()
            print("updatedUI")
        }


    }

}//End of getmoviedata


override func prepare(for segue: UIStoryboardSegue,sender: Any?){

    // Create a variable that you want to send
    let currentMovie = self.movieArray[movieIndex]


    if let destinationVC = segue.destination as? DetailsViewController{
        destinationVC.currentMovie = currentMovie
    }

}

func updateUI(){
    //self.posterLoading.stopAnimating()
    if uiMoviePoster == nil{
    print(uiMovieTitle.debugDescription)
    }
    else{
        print("first time debugID: " + uiMovieTitle.debugDescription)
    uiMovieTitle.text = self.movieArray[movieIndex].title
    uiMoviePoster.image = self.movieArray[movieIndex].poster
    }

}


}

Upvotes: 0

Views: 63

Answers (1)

Luzo
Luzo

Reputation: 1374

You want to grab a sharedInstance not instantiate from a storyboard

let movieVC = ViewController.sharedInstance()

but I still do not understand why do you need to do it like this

Upvotes: 1

Related Questions