I get the Warning "Variable 'userArray' was never mutated; consider changing to 'let' constant" in my code and my variable isn't being changed for some reason? I included some print statements to try and figure out what is running and what isn't. Here is what Prints: "Users appended - []", "Found ["Test User"]"
static func getBossSubs(bossID: String, completion: @escaping (Result<UserNames, Error>) ->
()) {
let pred = NSPredicate(format: "uniqueID = %@", bossID)
let sort = NSSortDescriptor(key: "creationDate", ascending: false)
let query = CKQuery(recordType: RecordType.Users, predicate: pred)
query.sortDescriptors = [sort]
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["subscribedBosses"]
operation.resultsLimit = 50
operation.recordFetchedBlock = { record in
DispatchQueue.main.async {
guard let subs = record["subscribedBosses"] as? [String] else {
print("Error at screenName")
completion(.failure(CloudKitHelperError.castFailure))
return
}
var userArray = UserNames() //Error that it should be a LET is here.
for boss in subs{
CloudKitHelper.getBossScreenName(bossID: boss) { (result) in
switch result{
case .success(let name):
userArray.names.append(name) //works fine
print("Found \(userArray.names)") //Prints a name
case .failure(let er):
completion(.failure(er))
}
}
print("does this run?") // Only runs if No Name
completion(.success(userArray)) // contains no name or doesn't run?
}
}
}
operation.queryCompletionBlock = { (_, err) in
DispatchQueue.main.async {
if let err = err {
completion(.failure(err))
return
}
}
}
CKContainer.default().publicCloudDatabase.add(operation)
}
I call the code like this:
.onAppear {
// MARK: - fetch from CloudKit
self.userList.names = []
let myUserID = UserDefaults.standard.string(forKey: self.signInWithAppleManager.userIdentifierKey)!
// get my subs projects
CloudKitHelper.getBossSubs(bossID: myUserID) { (results) in
switch results{
case .success(let user):
print("Users appended")
self.userList.names = user.names
case .failure(let er):
print(er.localizedDescription)
}
}
}
As you have it, userArray
is an object:
var userArray = UserNames()
When you append stuff to the names
property of the object, you aren't mutating the object, you are changing the content of one of its properties. If you aren't mutating the object (i.e. changing what properties it has), you should use let
.
Does anything break if you just change it to let
like Xcode is suggesting?
let userArray = UserNames()