'var' parameters are deprecated and will be removed in Swift 3

XcodeSwiftXcode7Swift3

Xcode Problem Overview


Alright so I just update Xcode to 7.3 and now I get this warning:

>'var' parameters are deprecated and will be removed in Swift 3

How to fix this when I need to use the var in this function:

public func getQuestionList(var language: String) -> NSArray {
    if self.data.count > 0 {
        if (language.isEmpty) {
            language = "NL"
        }
        return self.data.objectForKey("questionList" + language) as! NSArray
    }
    
    return NSArray()
}

Xcode Solutions


Solution 1 - Xcode

The discussion of the removal of Var from a function parameter is fully documented within this submission on GitHub: Remove Var Parameters

In that document you will find that people often confuse var parameters with inout parameters. A var parameter simply means that the parameter is mutable within the context of the function, while with an inout parameter the value of the parameter at the point of return will be copied out of the function and into the caller's context.

The correct way to solve this problem is to remove var from the parameter and introduce a local var variable. At the top of the routine copy the parameter's value into that variable.

Solution 2 - Xcode

Have you tried to assign to a new var

public func getQuestionList(language: String) -> NSArray {
    var lang = language
    if self.data.count > 0 {
        if (lang.isEmpty) {
            lang = "NL"
        }
        return self.data.objectForKey("questionList" + lang) as! NSArray
    }

    return NSArray()
}

Solution 3 - Xcode

Just add this one line at the beginning of the function:

var language = language

and the rest of your code can stay unchanged, like this:

public func getQuestionList(language: String) -> NSArray {
    var language = language
    if self.data.count > 0 {
        if (language.isEmpty) {
            language = "NL"
        }
        return self.data.objectForKey("questionList" + language) as! NSArray
    }

    return NSArray()
}

Solution 4 - Xcode

A lot of people are suggesting an inout parameter, but that's really not what they're designed for. Besides, it doesn't allow calling the function with a let constant, nor with a string literal. Why don't you simply add the default value to the function signature?

public func getQuestionList(language language: String = "NL") -> NSArray {
    if data.count > 0 {
        return data.objectForKey("questionList" + language) as! NSArray
    } else {
        return NSArray()
    }
}

Just make sure to not call getQuestionList with the empty string in case you want the default language, but just leave out the parameter:

let list = getQuestionList() // uses the default "NL" language

Solution 5 - Xcode

public func getQuestionList(language: inout String) -> NSArray {
if self.data.count > 0 {
    if (language.isEmpty) {
        language = "NL"
    }
    return self.data.objectForKey("questionList" + language) as! NSArray
}

return NSArray()

}

Solution 6 - Xcode

I think @Harris and @garanda answers are the best approach.

Anyway in your case, there isn't need of a var, you can do:

public func getQuestionList(language: String) -> NSArray {
    if self.data.count > 0 {
        return self.data.objectForKey("questionList" + (language.isEmpty ? "NL" : language)) as! NSArray
    }
    return NSArray()
}

Solution 7 - Xcode

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html

In-Out Parameters

Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake. If you want a function to modify a parameter’s value, and you want those changes to persist after the function call has ended, define that parameter as an in-out parameter instead.

You write an in-out parameter by placing the inout keyword right before a parameter’s type. An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value. For a detailed discussion of the behavior of in-out parameters and associated compiler optimizations, see In-Out Parameters.

You can only pass a variable as the argument for an in-out parameter. You cannot pass a constant or a literal value as the argument, because constants and literals cannot be modified. You place an ampersand (&) directly before a variable’s name when you pass it as an argument to an in-out parameter, to indicate that it can be modified by the function.

NOTE

In-out parameters cannot have default values, and variadic parameters cannot be marked as inout.

Here’s an example of a function called swapTwoInts(::), which has two in-out integer parameters called a and b:

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

The swapTwoInts(::) function simply swaps the value of b into a, and the value of a into b. The function performs this swap by storing the value of a in a temporary constant called temporaryA, assigning the value of b to a, and then assigning temporaryA to b.

You can call the swapTwoInts(::) function with two variables of type Int to swap their values. Note that the names of someInt and anotherInt are prefixed with an ampersand when they are passed to the swapTwoInts(::) function:

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"

The example above shows that the original values of someInt and anotherInt are modified by the swapTwoInts(::) function, even though they were originally defined outside of the function.

NOTE

In-out parameters are not the same as returning a value from a function. The swapTwoInts example above does not define a return type or return a value, but it still modifies the values of someInt and anotherInt. In-out parameters are an alternative way for a function to have an effect outside of the scope of its function body.

Solution 8 - Xcode

Here is another idea. My use case was to pass around a string array to append to it, for which the array must be passed in mutably. I did not want to have state in my class for this either. So I made a class that holds the array and pass that. Depending on your use case it may seem silly to have a class that holds just that one variable.

private class StringBuilder {
	var buffer: [String] = []
	
	func append(_ str: String) {
		buffer.append(str)
	}
	
	func toString() -> String {
		return buffer.joined()
	}
}

I only use append and joined methods on the array so it was easy to change the type with minimal other changes to my code.

Some example usage:

private func writeMap(map: LevelMap, url: URL) -> Bool {
	let buffer = StringBuilder()
	
	if !writeHeader(map: map, buffer: buffer) {
		return false
	}
	if !writeFloors(map: map, buffer: buffer) {
		return false
	}
	
	let content = buffer.toString()
	do {
		try content.write(to: url, atomically: true, encoding: .utf8)
		return true
	} catch {}
	return false
}

private func writeHeader(map: LevelMap, buffer: StringBuilder) -> Bool {
	buffer.append("something here ...\n")
	return true
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSDWView Question on Stackoverflow
Solution 1 - XcodeTr0yJView Answer on Stackoverflow
Solution 2 - XcodegarandaView Answer on Stackoverflow
Solution 3 - XcodeElijahView Answer on Stackoverflow
Solution 4 - XcodeTim VermeulenView Answer on Stackoverflow
Solution 5 - XcodeAbdul Rahman KhanView Answer on Stackoverflow
Solution 6 - XcodeSimone PistecchiaView Answer on Stackoverflow
Solution 7 - XcodeMustafa MohammedView Answer on Stackoverflow
Solution 8 - XcodewebjprgmView Answer on Stackoverflow