Swift 4: Type of expression is ambiguous without more context inside loop

Viewed 6010

I have a question:

I'm retrieving a long string made of some base 64 strings attached together with ";" separating each of them inside said string.

Here's my code:

   if(item.photo != "null"){
            let b64fullstring = item.photo
            if(b64fullstring!.contains(";")){
                let photos = b64fullstring!.split(separator: ";")
                
                for pic in photos{
                    let base64encodedstring = pic
                    let decodedData = Data(base64Encoded: base64encodedstring!, options: Data.Base64DecodingOptions.ignoreUnknownCharacters)!
                    let decodedString = String(data: decodedData, encoding: .utf8)!
                    print(pic)
                }
            }
        
        
        } 

Its gives me the following error on the "data" function; Type of expression is ambiguous without more context I really don't get it. When working on a single string, it works perfectly fine. But when using a loop, it gives this message for some reason.

Thank you for taking some of your time for helping me.

1 Answers

Swift errors are not very helpful. The problem there is that split method returns an array of substrings:

func split(separator: Character, maxSplits: Int = Int.max, omittingEmptySubsequences: Bool = true) -> [Substring]

And the Data initializer expects a String:

init?(base64Encoded base64String: String, options: Data.Base64DecodingOptions = [])

You just need to initialize a new string from your substring:

if let photos = b64fullstring?.split(separator: ";") {
    for pic in photos {
        if let decodedData = Data(base64Encoded: String(pic), options: .ignoreUnknownCharacters) {
            if let decodedString = String(data: decodedData, encoding: .utf8) {
                print(pic)
            }
        }
    }
}

Another option is to use components(separatedBy:) method which returns an array of strings instead of substrings:

func components<T>(separatedBy separator: T) -> [String] where T : StringProtocol

if let photos = b64fullstring?.components(separatedBy: ";") {
    for pic in photos {
        if let decodedData = Data(base64Encoded: pic, options: .ignoreUnknownCharacters) {
            if let decodedString = String(data: decodedData, encoding: .utf8) {
                print(pic)
            }
        }
    }
}
Related