Parse-Swift: Wrong image data when fetching image

New Issue Checklist

Issue Description

I am seeing issues when fetching an image. When i fetch an image for the first time, it loads the image corretly. But when it then tries to load for the second time, the image is broken. I looked at what the downloaded image looks like when opening in a text editor.

I noticed it doesn’t contain data, but a path. This is an example: file:\/\/\/var\/folders\/y5\/3qbps9t11cb2fz7lh1x8bw7w0000gn\/T\/com.app.myApp\/CFNetworkDownload_rDopeR.tmp

My uploaded images in the Database are valid images.

I want to point out that this way of fetching images always worked for me. It’s since the Beta’s that there is something wrong, but I don’t find anything on the Apple Developer known issues page.

Steps to reproduce

This is an example of code I use.

let modelQuery =  Model.query()
modelQuery.find { result in
    switch result {
    case .success(let model):
        if let imageURL = model.image?.localURL {
            print("imageURL: \(imageURL)")
            if let imgData = try? Data(contentsOf: imageURL) {
                print("imgData: \(imgData)")
                print("imgData as string: \(String(decoding: imgData, as: UTF8.self))")
                self.imageData = imgData
            }
        } else {
            model.image?.fetch(completion: { result in
                switch result {
                case .success(let fetchedImage):
                    if let localImageUrl = fetchedImage.localURL {
                        print("localImageUrl: \(localImageUrl)")
                        if let imgData = try? Data(contentsOf: localImageUrl) {
                            print("imgData: \(imgData)")
                            print("imgData as string: \(String(decoding: imgData, as: UTF8.self))")
                            self.imageData = imgData
                        }
                    }
                case .failure(_):
                    break
                }
            })
        }
        self.model = model
    case .failure(_):
        break
    }
}

This is my log:

Schermafbeelding 2021-09-06 om 17 25 04

Actual Outcome

file:\/\/\/var\/folders\/y5\/3qbps9t11cb2fz7lh1x8bw7w0000gn\/T\/com.app.myApp\/CFNetworkDownload_rDopeR.tmp

Expected Outcome

Image data

Failing Test Case / Pull Request

  • 🤩 I submitted a PR with a fix and a test case.
  • 🧐 I submitted a PR with a failing test case.

Environment

Parse Swift

  • SDK version: 1.9.8
  • Operating system (iOS, macOS, watchOS, etc.): iOS, macOS
  • Operating system version: iOS 15 Beta 8, Monterey 12.0 Beta 6

Server

  • Parse Server version: 4.4.0
  • Operating system: Back4App

Logs

localImageUrl: file:///Users/name/Library/Containers/com.app.myApp/Data/Library/Application%20Support/parse/com.app.myApp/Downloads/d48e0511e7660ab8e59fa2bb74cd48a4_1600.png
imgData: 123 bytes
imgData as string: "file:\/\/\/var\/folders\/y5\/3qbps9t11cb2fz7lh1x8bw7w0000gn\/T\/com.app.myApp\/CFNetworkDownload_rDopeR.tmp"

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 53 (50 by maintainers)

Most upvoted comments

It looks like if the file is already downloaded, it takes the path to that cached file and puts in the file Parse creates. But this only happens if the filename is the exact same, and if it already cached that file via .fetch.

This should work, fetching a file with the same url should yield the same file, so it’s better to use cache. If you are changing the file, it should have a different url than the previous file or you should ignore cache.

Adding the custom cachePolicy fixes the issue for me. But I don’t know if you think there might be a bug somewhere else?

I’ve tested it and don’t see any issues. If you find a bug, you can open an issue. I recommend you look at my earlier comment https://github.com/parse-community/Parse-Swift/issues/226#issuecomment-917667292 and if you can’t find a bug or fix your problem, then add the cache policy .reloadIgnoringLocalCacheData option which will re-download the file every time you fetch instead of using cache.

@cbaker6 Yes its on Monterey. Its running on an Intel iMac. But I actually started noticing the issue on the Beta software of iOS 15.

I’ll know more next week to see if it still persists on the official version of iOS 15.

Also want to mention that this issue is not a really big problem for my app. I started recreating my app in Swift instead of objective c. So i then knew that ParseSwift was in a really early stage so things could fail.

I also decided to target iOS 15 and macOS Monterey since Swift and SwiftUI got some important/big improvements.

So the version I am developing now is not in production yet.

So next week I’ll know more and investigate the issue more and keep you informed.

You should also checkout your cache policy: https://github.com/parse-community/Parse-Swift/blob/1a30fb60191b41b4d4fbb5c5bf528d0277fb5c69/Sources/ParseSwift/Parse.swift#L70-L74

You can enable CORS in your index.js on your server by:

const cors = require('cors');

var app = express();
app.use(cors());
...

What happens when you use the latest version of Xcode 12? If this only occurs in Xcode 13 beta, it’s probably not worth a fix until 13 goes Gold. If you can find some documentation that states Xcode 13 is changing the way downloaded data is handled, then I can take a look to see how to adjust.