Невозможно изменить параметры функции в теле функции

У меня есть определение метода в быстром проекте:

class func fireGetRequest(urlString: String!, username: String?, password: String?, completionBlock:(NSDictionary)->Void) {
    //check if user passed nil userName
    if username == nil || password == nil {
        // retrieve userName, password from keychain
        // here we have OR check since we have single value from pair it is of no use and can be considered as corrupted data
        // so it is better to retrieve stable data from keychain for further processing
        let (dataDict, error) = Locksmith.loadDataForUserAccount(kKeychainUserAccountName)

        // no error found :)
        // use data retrieved
        if error == nil {
            username = dataDict[kKeychainUserNameKey]
            password = dataDict[kKeychainUserPwdKey]
        }
    }

    // do something with username, password
}

Здесь я делаю следующие вещи:

  1. Проверка, является ли какое-либо имя пользователя, пароль нулевым или нет
  2. Если какое-либо из них равно нулю, то попытка установить соответствующие значения из словаря

Проблема в том, что я не знаю, как решить следующие ошибки:

введите здесь описание изображения

Аналогичный метод в target-c работает отлично:

+ (void)fireGetRequestWithUrlString:(NSString *)urlString userName:(NSString *)username userPwd:(NSString *)password{
    NSDictionary *dataDict = @{kKeychainUserNameKey: @"Some user name", kKeychainUserPwdKey: @"Some password"};

    if (!username || !password) {
        username = dataDict[kKeychainUserNameKey];
        password = dataDict[kKeychainUserPwdKey];
    }

    // do something with username, password
}

Любые идеи?

Обновление 1:

Как было предложено в ответах, я объявил параметры функции - имя пользователя и пароль как var, но затем начал получать следующие ошибки компиляции:

введите здесь описание изображения

Чтобы решить эту проблему, я набрал кастинг, но снова другая ошибка:

введите здесь описание изображения

При принудительном понижении ниже ошибка:

введите здесь описание изображения

Все равно непонятно :(

Наконец-то решено :)

if let dataDictionary = dataDict {
                    username = dataDictionary[kKeychainUserNameKey] as! String?
                    password = dataDictionary[kKeychainUserPwdKey] as! String?
                }

person Devarshi    schedule 29.08.2015    source источник


Ответы (2)


Параметры функции являются константами по умолчанию.

Явно определите изменяемые параметры как var

Свифт 2

class func fireGetRequest(urlString: String!, var username: String?, var password: String?, completionBlock:(NSDictionary)->Void) 

Свифт 3

class func fireGetRequest(urlString: String!, username: String?, password: String?, completionBlock:(NSDictionary)->Void){
   var username = username
   var password = password
   //Other code goes here
}
person vadian    schedule 29.08.2015
comment
Спасибо за ваш ответ, я попробовал, как было предложено, но снова столкнулся с ошибкой компиляции, см. Мой обновленный вопрос. - person Devarshi; 29.08.2015
comment
так как и username, и password являются необязательными, просто необязательными являются String username = dataDict[kKeychainUserNameKey] as? String. Если словарь содержит соответствующий ключ, вы получаете необязательную строку, в противном случае nil - person vadian; 29.08.2015
comment
спасибо, что направили меня в правильном направлении, я наконец смог решить последовательность ошибок компиляции, я приму ваш ответ :) - person Devarshi; 29.08.2015
comment
с решенным синтаксисом вы все равно получите ошибку времени выполнения, если словарь не содержит один из ключей, а as! String? является запутанным синтаксисом. Либо введите необязательный as?, либо принудительно as!, но опустите вопросительный знак после типа, в обоих случаях в случае успеха результирующий тип является типом целевой переменной. - person vadian; 29.08.2015

Вы должны объявить имя пользователя и пароль как var. По умолчанию let.

class func fireGetRequest(urlString: String!, var username: String?, var password: String?, completionBlock:(NSDictionary)->Void) {
    // ...
}

См. также: Язык программирования Swift: функции

Постоянные и переменные параметры

Параметры функции являются константами по умолчанию. Попытка изменить значение параметра функции из тела этой функции приводит к ошибке времени компиляции. Это означает, что вы не можете изменить значение параметра по ошибке.

Однако иногда для функции полезно иметь переменную копию значения параметра для работы. Вы можете избежать самостоятельного определения новой переменной в функции, указав вместо этого один или несколько параметров как параметры переменных. Переменные параметры доступны как переменные, а не как константы, и дают новую модифицируемую копию значения параметра, с которой может работать ваша функция.

person Bannings    schedule 29.08.2015
comment
Спасибо за ваш ответ, я попробовал, как было предложено, но снова столкнулся с ошибкой компиляции, см. Мой обновленный вопрос. - person Devarshi; 29.08.2015