0

in swift (Xcode) for ios development, I'm trying to set my UILabel's text to the elements of an array. This is for a simple project where when you press a button: out of a array for 50 elements, the 50 elements will be randomized and then 3 will be chosen and i want those 3 to be displayed on the UILabel, but I get the error that I cannot assign value of type '[String]' to type 'String?' (Swift). Here is my code main code

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var altLabel: UILabel!
    @IBOutlet weak var asianLabel: UILabel!
    @IBOutlet weak var bluesLabel: UILabel!
    @IBOutlet weak var classicalLabel: UILabel!
    @IBOutlet weak var countryLabel: UILabel!
    @IBOutlet weak var danceLabel: UILabel!
    @IBOutlet weak var edmLabel: UILabel!
    @IBOutlet weak var emotionalLabel: UILabel!
    @IBOutlet weak var euroLabel: UILabel!
    @IBOutlet weak var indieLabel: UILabel!
    @IBOutlet weak var inspirationalLabel: UILabel!
    @IBOutlet weak var jazzLabel: UILabel!
    @IBOutlet weak var latinLabel: UILabel!
    @IBOutlet weak var newAgeLabel: UILabel!
    @IBOutlet weak var operaLabel: UILabel!
    @IBOutlet weak var popLabel: UILabel!
    @IBOutlet weak var rbLabel: UILabel!
    @IBOutlet weak var reggaeLabel: UILabel!
    @IBOutlet weak var rockLabel: UILabel!
    @IBOutlet weak var rapLabel: UILabel!

    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 altButton(sender: UIButton) {

        let altSongs: [String] = ["Spirits by The Strumbellas", "Ride by Twenty One Pilots", "Ophelia by The Lumineers", "Dark Necessities by Red Hot Chili Peppers", "Bored to Death by Blink-182", "HandClap by Fitz And Tantrums", "Walking An A Dream by Empire Of The Sun", "Kiss This by The Struts", "Woman Woman by AWOLNATION", "First by Cold War Kids", "Way Down We Go by Kaleo", "Gone by Jr Jr", "Genghis Khan by Miike Snow", "Stressed Out by Twenty One Pilots", "Adventure Of A Lifetime by Coldplay", "2AM by Bear Hands", "Take It From Me by KONGOS", "Soundcheck by Catfish And The Bottlemen", "Brazil by Declan McKenna", "Destruction by Joywave", "Centuries by Fallout Boy", "Castle by Hasley", "First by Cold war Kids", "Unsteady (Erich Lee Gravity Remix) by X Ambadassadors", "Best Day Of My Life by American Authors", "Hymn For The Weekend by Coldplay", "Seven Nation Army by The White Stripes", "This is Gospel by Panic! At The Disco", "Riptide by Vance Joy", "Uma Thurman by Fallout Boy", "My Song Know What You Did In The Dark (Light Em Up) by Fall Out Boy", "Radioactive by Imagine Dragons", "Car Radio by Twenty One Pilots", "Walking On A Dream by Empire Of The Sun", "Viva La Vide by Coldplay", "Left Hand Free by Alt-J", "Tear in My Heart by Twenty One Pilots", "Death Of A Bachelor by Panic! At The Disco", "Demons by Imagine Dragons", "Emperor's New Clothes by Panic! At The Disco", "I Write Sins Not Tradegies by Panic! At The Disco", "Sail by AWOLNATION", "Twice by Catfish And The Bottlemen", "Colors by Hasley", "Nobody Really Cares If You Don't Go To The Party", "Courtney Barnett", "A Sky Full Of Stars", "On Top Of The World by Imagine Dragons", "Woman Woman by AWOLNATION", "Take Me T Church by Hozier"]

        var shuffled = altSongs.shuffle;
        shuffled = altSongs.choose(3)
        altLabel.text = shuffled  //(ending brackets are in place, just not shown here. **Rest of the code is just buttons structured in same format as this one**)

I'm only a beginner at iOS developing

Code for the methods: //(choose) and (shuffle)

import Foundation
import UIKit

extension Array {
    var shuffle: [Element] {
        var elements = self
        for index in indices.dropLast() {
            guard
            case let swapIndex = Int(arc4random_uniform(UInt32(count - index))) + index
                where swapIndex != index else {continue}
            swap(&elements[index], &elements[swapIndex])

        }
        return elements
    }
        mutating func shuffled() {
            for index in indices.dropLast() {
                guard
            case let swapIndex = Int(arc4random_uniform(UInt32(count - index))) + index
                where swapIndex != index
                    else { continue }
                swap(&self[index], &self[swapIndex])
            }
        }
        var chooseOne: Element {
            return self[Int(arc4random_uniform(UInt32(count)))]
        }
        func choose(n: Int) -> [Element] {
            return Array(shuffle.prefix(n))
        }
}
Ruchir Mehta
  • 1
  • 1
  • 3

3 Answers3

2

For your error: "unexpectedly found nil while unwrapping an Optional value", have a look at my post about them, understanding '!' and '?' is crucial for Swift development: What are '!' and '?' marks used for in Swift

Also, as other answers mentioned also, you are returning an array value instead you should give a String value and then assign it to your label.text value. For this, you can try below:

altLabel.text = "\(shuffled[0]), \(shuffled[1]), \(shuffled[2])"
Community
  • 1
  • 1
Burak
  • 525
  • 4
  • 24
  • 1
    I looked at your post and I understand, but I don't know where I would put any '?'s in my code. Also, when I inputted that code, it gave me an error saying I couldn't assign type '()' to type 'String?' – Ruchir Mehta May 24 '16 at 07:51
  • @RuchirMehta OK, according to what you said: "this is the line of code: altLabel.text = selectedThree[0] + " " + selectedThree[1] + " " + selectedThree[2]" and "... couldn't assign type '()' to type 'String?'", the problem is that 'shuffled' used in "altLabel.text = shuffled", returns an 'empty array', or 'nil'. So, there appears to be something you miss in your methods in "Array Extension" – Burak May 24 '16 at 09:11
  • I get the nil error when I use the code "altLabel.text = selectedThree[0] + " " + selectedThree[1] + " " + selectedThree[2]"" and when I use the code your gave me "altLabel.text = "\(shuffled[0]), \(shuffled[1]), \(shuffled[2])"". I used to get the "type '()' to type 'String?'" error when I ran your code, but now there is no error. (the backslash is there; it's just not being shown in the comment) – Ruchir Mehta May 24 '16 at 14:31
1
var shuffled = altSongs.shuffle; // Line 1
shuffled = altSongs.choose(3)    // Line 2
altLabel.text = shuffled         // Line 3

Replace the above code with

let shuffled = altSongs.shuffle;
let selectedThree = shuffled.choose(3)
altLabel.text = selectedThree[0] + " " + selectedThree[1] + " " + selectedThree[2]

Here you shuffle the array and put it in shuffled then pick array of first three elements in selectedThree.

selectedThree is an array of strings. We can either iterate the array to get the string or just use the first three elements.

BangOperator
  • 4,377
  • 2
  • 24
  • 38
  • I still get the same error (cant assign type '[String]' to type 'String?' when doing that correction – Ruchir Mehta May 24 '16 at 05:30
  • Add the code for implementation of the methods 'shuffle' and 'choose' in your question. – BangOperator May 24 '16 at 05:33
  • Now I'm getting the fatal error: unexpectedly found nil while unwrapping an Optional value – Ruchir Mehta May 24 '16 at 05:58
  • I put in that code and I'm still getting the same fatal error. I even tried recreating the connection as suggested in other posts about the fatal error, but nothing is working. – Ruchir Mehta May 24 '16 at 07:00
  • @RuchirMehta I have tried and tested it. There should not be a problem. Try cleaning your project. Please cross check you code from this ViewController https://www.dropbox.com/s/xht4wjhabrmzvl8/ViewController.swift?dl=0 – BangOperator May 24 '16 at 07:04
0

I don't know where did you define shuffle and choose and I think you implemented them incorrectly.

I think you can just create a choose extension method that returns an array of strings:

func chooseFromArray<T>(array: [T], amountToChoose: Int) -> [T] {
    var returnVal: [T] = []
    var arrayCopy = array
    for _ in 0..<amountToChoose {
        let chosen = Int(arc4random_uniform(UInt32(arrayCopy.count)))
        returnVal.append(arrayCopy[chosen])
        arrayCopy.removeAtIndex(chosen)
    }
    return returnVal
}

And then you can just call it like this:

var chosenSongs = chooseFromArray(altSongs, amountToChoose: 3)

You said you want to display an array in a label. So I guess you want to do it like this?

altLabel.text = chosenSongs.joinWithSeparator(", ")

I think that should fix it.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • so yeah, as seen in other comments, i still get this fatal error: unexpectedly found nil while unwrapping an Optional value – Ruchir Mehta May 24 '16 at 05:44
  • @RuchirMehta Somewhere in your code, you are passing a 'nil' value to a 'var', which you had defined it with '!', that's probably why you are getting this error. – Burak May 24 '16 at 07:18
  • 1
    @RuchirMehta I think the error is caused by some other parts of your code which you didn't show in this question. I suggest you to find out where the error *exactly* occurred. Then, you can ask a new question concerning the error. Remember to tell us what you have tried to solve it! After that, you can accept one of the answers to this question. – Sweeper May 24 '16 at 07:33
  • @Burak The only "!" I have used are for the UILabel outlets and in the methods for choose and shuffle, ex: "where swapIndex != index" – Ruchir Mehta May 24 '16 at 07:33
  • @sweeper How do i pinpoint the exact location of the error? All Xcode shows me is a red breakpoint on the line of code where it stopped working. – Ruchir Mehta May 24 '16 at 07:35
  • Ah! I know what might have happened! Do you see those circles beside the IBOutlets? Are they filled in or or they hollow? If they are hollow, I know exactly where went wrong. @RuchirMehta – Sweeper May 24 '16 at 07:36
  • @RuchirMehta the red line is where the error occurred! Can you tell me which line it is? – Sweeper May 24 '16 at 07:36
  • @RuchirMehta In that case, the code is somehow assigning 'nil' value to those 'outlets' – Burak May 24 '16 at 07:44
  • @Sweeper this is the line of code: altLabel.text = selectedThree[0] + " " + selectedThree[1] + " " + selectedThree[2] (In all the answers providing recommendations of code to use, the line where you set the altLabel.text equal to the String has always been the place where the fatal error occurs) To address your other question about the hollow circles: they are all filled in. – Ruchir Mehta May 24 '16 at 07:45
  • @Burak Do you know what I can do to stop it from assigning nil value to the outlets. In another answer's comment section, I was instructed to clean my whole project and after I did so, I still faced the same problem. – Ruchir Mehta May 24 '16 at 07:46