Contentful logo

Contentful Community

Fallback locale for assets

Hi!

I’m building an iOS app backed by Contentful. I have an Article referencing an array of images. My articles are localized into several languages, but the images are not. I’ve setup so that articles fallback to my default language, but I can’t find this option for images. I’m using the Contentful Persistence Swift library to fetch/sync my data.

Everything works fine, except that my images only get data for the default language. Is it possible to activate locale fallback for images somehow?

Thanks,
Marthin

1 Like

Hi @marthinfreij!

I think it’s not possible to set up fallback for images now. So, best way probably would be adding images for all locales or changing the changing default locale so it would be the same as fallback (not sure if it could work for you though).

Hey @marthinfreij :wave:,

JP here, maintainer of contentful.swift and contentful-persistence.swift. You should be able to leverage the fallback chain when using the Contentul Swift stack, but things get a little trickier with persistence.

The /sync endpoint always sends content for all locales, so in order to take advantage of the Contentful fallback locale logic, this logic must be implemented client-side. Luckily, the SDK does implement it. However, since CoreData doesn’t allow any dictionary properties on your types, we create a separate entity for each locale in your space to save localized data. If you have 4 locales set up in your space, there will be 4 CoreData entities per asset. These 4 entities would all have the same identifier, so to uniquely identify each, the Persistable protocol requires that you add an @NSManaged var localeCode: String to your NSManagedObject subclasses. You must init your sync manager with a localization scheme like so in order for entities to be saved to CoreData for each locale.

let syncManager = SynchronizationManager(client: client, localizationScheme: .all)

Additionally, you will have to specify a locale when fetching from CoreData. The localized asset that is retrieved in this manner will have values in the fallback locale code if there was is content in the "es-MX" locale:

let assetId = "3Ck6MRrAJ2CaiasGKqeyao"
let assets: [Asset] = try self.store.fetchAll(type: Asset.self,  predicate: NSPredicate(format: "id == '\(assetId)' AND localeCode == 'es-MX'"))

I hope that helps!

3 Likes

Hey @loudmouth

Thanks! That’s more or less exactly the workaround I did. I extended the Asset entity to return a non nil urlString with the same id.

extension Asset {
    
    var fallbackUrlString: String? {
        
        get {
            
            let request = NSFetchRequest<Asset>(entityName: "Asset")
            request.predicate = NSPredicate(format: "id == %@ AND urlString != nil", self.id)
            request.propertiesToFetch = ["urlString"]
            
            if let result = try? self.managedObjectContext?.fetch(request).first {
                if let result = result {
                    return result.urlString
                }
            }
            
            return nil
        }
    }
}

Glad you got something to workaround while you were waiting for a reply!

I’m curious if changing your fetch request predicate to specify the locale like in my comment above works for you. The reason I would suggest using the locale in your query as opposed to finding a non-nil urlString is that the non-nil check will return multiple results if you do have a media file on your asset in more than 1 locale. id AND localeCode will guarantee one unique entity which should respect the values expected with fallback logic so you can be sure that you’re seeing the appropriate asset for the locale of interest.

Does that work for you?

1 Like