lastminute.com logo

Technology

Widget iOS: how to fix the image bundling problem

fabrizio_duroni
fabrizio duroni
marco_de_lucchi
marco de lucchi

Discover how we had a long day debugging WidgetKit problems with images.


In the previous post, we presented our FriYaY project: an inspirational iOS widget. We were so excited to have our first widget in production that we forced asked all our colleagues to give it a try.
Unfortunately, for some people, the widget was loading in a broken state: as you can see from the image below, the assets were not loading.

Widget not loading
Widget not loading

We were heartbroken. We tested the widget carefully before going to production, on multiple iPhones and iPads with different iOS and iPadOS versions, even with the iOS 16 Developer Beta build, and we never had this behaviour.
Soon we found ourselves deep into the code, trying to catch the bug. There was not a single line in the Xcode log that was pointing us to the right solution.

We tried to:

  • debug the REST services, to understand if there was a bug in the API
  • debug the Network Client code, to understand if there were some errors in the deserialization of the JSON or in the image download
  • debug the UI, to understand if we were making mistakes with the Image display code.

During the investigation we noticed that both the images bundled inside the extension (e.g. the one shown in the widget picker before installing it) and the ones downloaded from the API were not working. We were able to replicate the issue only on iPhone 11 (A13 Bionic Chip) and older.

We finally checked the general system log using the Console.app, to better understand what was happening at system level. To avoid having noise in the logs, we created and empty app project with attached our widget extension. While running the test app on an iPhone 11, we finally found the problem.

Debugging the code with Console.app
Debugging the code with Console.app

As you can see from the screenshot, the widget was failing to archive because the image used as background (what we called inspiration image in the previous posts) was too big. This was causing a memory leak (see CGImageCopyResourceImageSource logs) that prevented the code from opening the images causing the “broken widget” state reported above.
After some searches we found this thread on the Apple Developer Forum, where they were suggesting to reduce images’ size using some UIImage extension code.

So how did we solve the problem? We simply sized our images in the right way emoji-laughing.
Using the WidgetKit Human Interface Guidelines from Apple, we gave to the images the size based on the width of the widgets on the various iPhones. If you can’t approach the problem in this way, you can still use the extension code for UIImage mentioned in the Apple Developer Forum above.

extension UIImage {
  func resized(toWidth width: CGFloat, isOpaque: Bool = true) -> UIImage? {
    let canvas = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
    let format = imageRendererFormat
    format.opaque = isOpaque
    return UIGraphicsImageRenderer(size: canvas, format: format).image {
      _ in draw(in: CGRect(origin: .zero, size: canvas))
    }
  }
}

Conclusion

The journey into WidgetKit is not finished yet, if you want to know more about it check the links below:


About fabrizio duroni

fabrizio_duroni
Software Engineer

Fabrizio is a Software Developer with 15+ years of experience. He specialised in mobile application development, computer graphics and web development. He ❤️ computers 💻, music 🎸, tattoo, videogames 👾 and drawing ✏️. He is also the maintainer of this blog 👷‍.

About marco de lucchi

marco_de_lucchi
Software Engineer

Marco is a Mobile Software Developer at lastminute.com, having joined the App Team in 2019. He is passionate about Apple and iOS development 📱, always focused on creating exceptional user experiences. Fun fact: you can quiz him about SwiftUI or Taylor Swift!


Read next

React Universe 2024

React Universe 2024

fabrizio_duroni
fabrizio duroni
sam_campisi
sam campisi

Let's dive into the talks from React Universe 2024 that stood out to us the most and share the key insights we gained. From innovative debugging tools to cross-platform development strategies, we’ll walk you through what we found valuable and how it’s shaping our approach to React and React Native development. [...]

Tech Radar As a Collaboration Tool

Tech Radar As a Collaboration Tool

rabbani_kajamohideen
rabbani kajamohideen

A tech radar is a visual and strategic tool used by organizations to assess and communicate the status and future direction of various technologies, frameworks, tools, and platforms. [...]