The Breakroom

Clicker 2.0

February 3, 2023

By Craig Hockenberry

Clicker running on Apple Watch. The green count button is displayed along with the number 42

Back in 2015, we released our first watchOS app. Clicker is a simple app with a simple goal: a way to keep track of something important in your life using your Apple Watch. It’s been used by hundreds of thousands of customers.

For me, Clicker kept me swimming in the ocean, for others the count was something different — these are just some of the things we’ve seen in reviews and social media:

  • Laps while running on a track
  • Rests in an orchestral rehearsal
  • Ounces of water each day
  • Number of times smoking to cut back
  • Consecutive days exercising
  • Number of books read
  • Tips from customers
  • Rows while knitting
  • Trick-or-treater management
  • Pizza folding (yum!)

It’s eight years later and we’re all still counting! With recent advances in the capabilities of watchOS and iOS, it felt like a good time to give the product a makeover. Here are the new things that both we and our customers want:

  • A beautiful new plus button that matches the color of the watch complication
  • Customizable color now uses an array of pleasing and standard hues
  • Settings can now be changed directly on Apple Watch
  • New settings to manually set count and update in tens or dozens
  • Plus button now works on iPhone and iPad
  • All data automatically synced to all devices and watch complications
  • Light and dark mode are supported on iPhone and iPad

And the good news is that Clicker is still FREE to download and use. If you really want to show your thanks, make sure to try out one of our other apps. Enjoy!

Masto-do or Masto-don’t?

January 27, 2023

By Webmaster

Let’s just say that January 12th was expected, yet still surprising. We knew the cutting and slashing at Twitter would affect us at some point, but how we’d get eviscerated was an unknown.

Many other people saw it was coming as reality began to sink in at the end of October. We’ve been asked, countless times: “Are you folks working on a Mastodon app?”

The answer isn’t a simple one.

(But honestly, we loved seeing all the creative names that people have come up with when asking the question!).

First Things First

Our current priority is completing chapter 3 of Frenzic: Overtime on Apple Arcade. The game has been immensely fun to work on and we’re grateful Apple gave us a long-awaited opportunity to revisit our first game for the iPhone. We’ll be working on Frenzic until late spring of this year. We’re a small team and don’t have the resources to work on more than one major internal project at a time. Any new social media app will unfortunately have to wait.

Beyond Twitter

Even though we’re not currently working on an app, we’re all definitely thinking about the Fediverse and are active on Mastodon. We feel like this is a good time to step back, slow down, and think about where we want to head post-Twitter.

As we speak, teams of talented developers are building a plethora of great apps for Mastodon. It’s going to be a crowded, more mature market, and we don’t like being latecomers. We have a long history of firsts on Twitter: the first app ever in 2007, the first iPhone app in 2008, and the first iPad app in 2010.

However, the Fediverse is bigger than Mastodon: A new thing called ActivityPub is being used to power not just Mastodon but a lot of other interesting services.

This open standard is exciting, and it’s just one of the things we’ll be exploring and experimenting with as we decide which direction to take later this year.

Stay Tuned

So yeah, a simple question without a simple answer.

But one thing is for sure: When the time comes, we won’t be able to do it without your help. We’re grateful for all the love you’ve shown us and Twitterrific in the past, and we know we can count on you for support and feedback for whatever comes next!

To keep apprised of what our future looks like, make sure to follow our new @Iconfactory account (on our shiny new Mastodon instance!)

Announcing Linea Sketch 4.2

January 24, 2023

By Ged Maheux

Today’s Linea update brings several new and exciting features designed to give you more options while sketching and when moving images into and out of the app. Version 4.2 also includes a bevy of improvements that reduce friction when transforming artwork, provide new and updated templates, and much more. 

The Nitty Gritty

Linea’s new Organic Ink makes it easy to create textured strokes and fills when sketching. Use the Pen tool to create rough-edged strokes, and even vary the size with pressure sensitivity. It also works in conjunction with the Fill tool to quickly create solid areas with organic edges.

Organic Ink gives your sketches a rustic and natural appearance that is unlike anything previously offered in Linea. You can even tilt your Apple Pencil as you draw to quickly shade wide areas with texture.

The Ins and Outs

Linea 4.2 brings the ability to import and export a much wider range of file types that make your workflows faster and easier. Import multiple images simultaneously, including PNG, JPEG, TIFF, and even Photoshop PSD files. Linea also supports the ability to import multi–page PDF files to make annotating documents quick and painless.

Users of the venerable drawing app Paper, by 53/WeTranfer, can now easily transfer their creations into Linea. When imported via iCloud, Paper files are converted into a layered sketch document, perfect for further refinement in Linea.

Something Bold, Something Undo

ZipLines now respond to pressure from the Apple Pencil as you draw, which means one end of the line can be thin and light and the other can be thick and bold, or any combination. The line updates as you drag the end point and adjust the pressure, allowing you to get exactly the result you want.

ZipLines now respond to pressure as you draw allowing you to vary the opacity, thickness and shading on the fly.

Undoing now restores each step of a ZipShape transformation, all the way back to your original stroke. This means you no longer have to start over each time you transform a perfect square, circle, or polygon, which is a great time saver.

A Few More Things

We’ve added a new, larger 1×1 grid and a new iPhone design template that includes Apple’s Dynamic Island. Sketches also remember if their orientation was locked via the Canvas Compass, so you don’t have to re-lock each time you open them.

Version 4.2 also includes improvements to the iOS sharing extension, subtle efficiencies to the user interface when selecting layers, the ability to merge selections into completely different layers, as well as improved handling of large images when they are imported into Linea.

Today’s update is the perfect opportunity to see why so many people call Linea their favorite sketchpad. Visit Linea’s version history page for the complete list of what’s new, and then head on over to the App Store and grab the FREE download of Linea Sketch. It’s where your ideas begin!

Twitterrific: End of an Era

January 19, 2023

By Sean Heber

Twitterrific has been discontinued.

A sentence that none of us wanted to write, but have long felt would need to be written someday. We didn’t expect to be writing it so soon, though, and certainly not without having had time to notify you that it was coming. We are sorry to say that the app’s sudden and undignified demise is due to an unannounced and undocumented policy change by an increasingly capricious Twitter – a Twitter that we no longer recognize as trustworthy nor want to work with any longer.

Since 2007, Twitterrific helped define the shape of the Twitter experience. It was the first desktop client, the first mobile client, one of the very first apps in the App Store, an Apple Design award winner, and it even helped redefine the word “tweet” in the dictionary. Ollie, Twitterrific’s bluebird mascot, was so popular it even prompted Twitter themselves to later adopt a bluebird logo of their very own. Our little app made a big dent on the world!

None of those amazing achievements would have been possible without the generous and loyal support of you, our wonderful customers and fans. Your financial support may have paid the bills, but your spiritual support enriched our souls and for that we can never thank you enough. You changed our lives forever.

But, as much as it pains us to say it, Twitterrific for iOS and macOS have now been removed from both App Stores. If you had a subscription on iOS, it will be automatically cancelled by the App Store.

Finally, if you were subscriber to Twitterrific for iOS, we would ask you to please consider not requesting a refund from Apple. The loss of ongoing, recurring revenue from Twitterrific is already going to hurt our business significantly, and any refunds will come directly out of our pockets – not Twitter’s and not Apple’s. To put it simply, thousands of refunds would be devastating to a small company like ours.

While this chapter may have ended, our story is not over. As long as we’re able, we’ll continue improving our other apps, creating new apps, doing amazing design work for our clients, and posting awesome wallpapers to Wallaroo and Patreon. Stick around!

State of the Twitterverse

January 13, 2023

By Ged Maheux

Last night at about 7:30pm PST, Twitterrific customers started reporting problems accessing Twitter via the iOS app.

News quickly spread on Twitter and Mastodon that a wide range of third party apps like Twitterrific, Tweetbot, Echofon, and many others had been disabled. Strangely, Twitterrific for macOS continues to work normally. We cannot say for certain why some clients are unaffected, but it seems possible that there is a new (seemingly unstated and unannounced) policy that is only being applied to apps with large numbers of users.

There’s been no official word from Twitter about what’s going on, but that’s unsurprising since the new owner eliminated the employees dedicated to keeping the API up and running smoothly, including the developer evangelists who previously provided communication with third-parties.

We wouldn’t know whom to reach out to at Twitter even if such people existed. We’re in the dark just as much as you are, sadly. 

As soon as we have a better understanding of what has happened, we’ll update this blog post and let you know. In the meantime, if you own a Mac you can use Twitterrific for macOS (but we don’t know how much longer this will last).

You can also follow @iconfactory on Twitter or find several of us on Mastodon: Ged, Sean, Craig, Talos and Anthony

We’d also like to say thank you to all the people who have reached out to us on Twitter and told us how much they appreciate Twitterrific and our dedication to making Twitter usable over the years. These kind words mean a great deal to every one of us here at the Iconfactory. Quite honestly we wouldn’t be where we are today without your support of our apps like Twitterrific.

Stay tuned and beaks up!

Updated January 17th, 2023: We still have not received any clear communication as to why Twitter deactivated Twitterrific on January 13th. We have been respectful of their API rules, as published, for the past 16 years. We have no knowledge that these rules have changed recently or what those changes might be.

The Year In Review for 2022

December 16, 2022

By Ged Maheux

More than any other year in recent memory, 2022 brought big changes—some good, some bad, and some sad. During our 25 years in business we’ve learned to roll with all manner of punches and continue forging ahead. This year was no different. 

Old Friends

This year brought a string of notable updates to some of our most popular apps. Linea Sketch, loved by artists and designers from around the world, got a big 4.1 update. This brought great features like Clear Ink that turns any of Linea’s drawing tools into textured erasers, and Project Collections that help you stay organized as you create. We’re now working on Linea 4.2 for release early in 2023, and we’re excited by where the app is heading!

In April we unearthed CandyBar (originally launched circa 1995?) and shipped an update called the Sugar Free Edition™, which let CandyBar fans continue to browse their icon collections on modern versions of macOS. Though the app remains officially unsupported, fans were surprised and delighted to find collecting icons still tasted as sweet as they remembered.

Spring also saw the arrival of Chapter 2 of Frenzic: Overtime on Apple Arcade, bringing over 30 new and exciting levels with unique, fast-paced puzzles to solve. Frenzic’s Test Lab also received new daily challenges for players from around the world to compete in for the spot of top bot.

Tot, our tiny hyper-focused note taking app, got an update in the summer which added smart bullets and iOS widgets as well as Apple Watch support a few months later.

Fresh Faces

We launched two great new apps in 2022, both of which scratched some personal itches we’ve had for many years.

WorldWideWeb was introduced in June as a free, personal web server to make developing websites a snap. The app makes running your own web server about as easy as can be and has been welcomed with open arms by the Mac and iOS community. Be sure to check it out! 

We celebrated our love of creating desktops and wallpapers with the launch of Wallaroo, an iOS app that makes it easy to browse our library of hundreds of handcrafted images. When you find one you like, you can use it right on your own device with a tap! The app includes a large collection of wallpapers that our Patreon members been enjoying since 2019, and the best part is that it keeps growing with new releases from us and other notable designers every week. As always, our Patreon subscribers enjoy additional, exclusive content every month both in and out of Wallaroo, plus sneak peeks at upcoming projects.

The Giant Blue Bird in the Room

If any one had told us Twitterrific would still be tweeting in 2022, nearly fifteen years after the app first launched, we wouldn’t have believed you. Despite all the turmoil and changes at Twitter over the years, Twitterrific has persisted.

Our users are some of the most dedicated, loyal, and wonderful people we’ve ever encountered, and if it wasn’t for them, we might have already bowed out of supporting Twitter.

Twitter’s new owner seems to be intent on tearing the company, its employees, and civil discourse itself apart at the seams. What all this means for third party apps like Twitterrific isn’t clear, but until the API flies away, Twitterrific, in its current state, will continue to support the service. We don’t know where it’ll go beyond that.

Saying Goodbye 

Change also came in a profoundly sad way this year. After a multi-year battle with cancer, we lost our dear friend and Iconfactory founder, Corey Marion. Needless to say we were all devastated. Corey was the very heart of The Iconfactory and his presence touched everything we did.

The outpouring of support his family and all of us received was amazing. He was a life that was loved and appreciated by all who knew and worked with him. We still miss him every single day.

Taking Time to Recharge

The road ahead may be uncertain but what’s rock solid is our appreciation of you, our loyal customers, friends, and fans. You make all this possible as we push into the new year and recharge our batteries. We wish all of you a very happy holiday. Stay safe, enjoy your time with family and friends, and we’ll see you all in 2023!

Tot 1.5 – Smarter Bullets and Watch Out

October 4, 2022

By Craig Hockenberry

Our last release of Tot introduced a new feature called Smart Bullets. These special bits of text made it easy to create lists where you could check off items. (Check out “What’s New?” in the app help and you’ll get a quick demo.)

One shortcoming with Smart Bullets was that you needed a mouse to manage them. And now with version 1.5, that’s been improved: there are keyboard shortcuts to both add and toggle Smart Bullets. Your hands never have to leave the keyboard!

We’ve also added support for printing out the contents of your dot. In today’s digital world, that seems kind of a weird feature until you realize that it’s a great way to create a quick PDF for email or to print a one-off shipping label.

Folks on iOS 16 will also be able to take advantage of the new system Find & Replace when editing text. After selecting some text, you’ll find “Find Selection” in the Edit menu. “Find” is also available if there is no selection. If you want to replace text or use other options, tap the magnifying glass menu.

There are also some user interface improvements. If you have aging eyes (/me raises hand) then the adjustable line height in the Format menu (macOS) or Settings (iOS) will be a welcome addition. We’ve also heard your customer feedback and made Tot’s menu bar icon a standard size and appearance. There’s even a new icon that matches the watchOS app.

Your menu bar is getting a new look, and there’s’ a new “Dot” app icon available.

Hello Tot Mini

Wait a second: watchOS app?

Yes, you can now tote Tot around on your wrist. It’s surprisingly handy: one of our beta testers is a distance runner and uses a dot for directions. Shopping lists and other kinds of reminders are also a natural fit.

In addition to viewing your text, you can also make simple additions with dictation or the Scribble keyboard. Full editing on the watch isn’t feasible, but it’s great to be able to quickly get a random thought into a dot and having it sync back to your phone or desktop!

Tot Mini is a watchOS 9 app and available to download as a separate purchase on the App Store. To learn more about Tot, check out the product website. Full details about this and other Tot releases is available in our version history.

Enchant Your Inktober with Linea Sketch

September 28, 2022

By Webmaster

October returns once again with an orange armful of pumpkin spice, a crisp autumn breeze, and a way to channel our creativity every day of the month. Inktober encourages artists, both amateur and professional alike, to pick up pen and pencil and express themselves by crafting a drawing each day based on the official list of prompts.

The official list of drawing prompts for Inktober 2022

For the past three years we’ve contributed to the cause by creating a set of handy templates for Linea Sketch that outlines the prompts for each of the 31 days in Inktober. This year’s list of templates is once again ready for download and broken out by page numbers that contain the prompt for that day’s drawing. The templates are perfect for those who like to have a uniform set of sketches for the entire month or who want to stay tight and focused on their daily creations.

As always, Linea’s Inktober 2022 templates are completely free, easy to set up, and should quickly get you on your way to joining in on the inking fun. Last year we created a short video tutorial on how to get the templates into Linea Sketch for the iPad that will help guide you through the process this year as well. Be sure to check it out

Lastly, don’t forget to tag your posts with #LineaSketch – we always share our favorite drawings over on Linea’s Instagram so it’s a great way to step into the lime light! Apply new screen protectors and charge those Apple Pencils because October will be here before you know it!

Wallaroo and SwiftUI (5 of 5)

September 23, 2022

By Sean Heber

We were getting near the end of Wallaroo development and the app was close to fully functional, but as mentioned at the tail of the previous post, there was still one more important thing that I had to figure out how to implement.

The wallpaper detail view has a popup with metadata about the wallpaper you are viewing. Some of that metadata takes the form of tags and tapping a tag needed to push a new page on the navigation stack.

Normally this would be relatively easily done with a NavigationLink but there was a wrinkle: The button that needed to have these links lived inside of a .popover which, when presented, is not part of the navigation stack! That resulted in the NavigationLink being disabled since from its point of view there was no navigation stack to push anything to.

Wallaroo’s tags let users quickly find similar content across the entire app

Luckily Apple introduced NavigationPath this year and it seemed like it might be possible to use it to solve this problem.

Of course since NavigationPath was a brand new API, there wasn’t a lot of information out there about how to work with it. Many of the quick “tutorial” posts that showed up within hours of the WWDC announcement didn’t help, either. (Unfortunately most were nothing more than reprints of Apple’s simple demonstration code which was immensely unhelpful.)

Those that went farther did things like tuck the NavigationPath into an ObserverableObject which was then added to the environment or passed explicitly to subviews for them to manipulate. I’m certainly not a SwiftUI style expert, but that didn’t feel right to me.

Fueled by my prior research into finding the “right” way to pass what I needed around for the parallax effect, I opted to model a solution based on the way that dismiss and openURL are implemented in SwiftUI itself: As an environment action.

Instead of passing an object around that was nothing more than a thin wrapper of the navigation path, I created an action struct that implemented callAsFunction() just as Apple does with DismissAction, OpenURLAction, RefreshAction and others. The root view then added the action to the environment so all child views could use it.

With this approach, the NavigationPath is private to the root view which remains in control of adding things to the path. The root view also already implemented .navigationDestination for the views in the navigation stack, so it made sense to me that it should own how pages get pushed, too.

When the detail view needs to open a new gallery page, it uses my new OpenPageAction from the environment to request the new page much like this: openPage(.gallery(.tag("abstract"))).

We also sometimes needed to present other standard views that were overlays of the whole UI (like the purchase screen) and all I needed to do was add a case to the Page enum and a new line to the function that opens the pages. The same mechanism that pushes a new view on the navigation stack can also now open a new modal popup without the caller needing to know the difference.

(Note: When the first iOS 16.1 beta dropped, we suddenly had a navigation regression where sometimes empty views were pushed on the navigation stack. I spent an afternoon and isolated a simple reproducible example [filed: FB11518877]. We reached out to multiple Apple engineers that we had contact with and eventually learned this is a known regression which is expected to be fixed before 16.1 ships. I implemented a workaround in the meantime – but fingers crossed!)

The last bit of polish we wanted before shipping was to make the favorite button do something a bit more fun when you pressed it.

Visual flourishes like the Favorite Heart animation add joy and tactility to Wallaroo

Gedeon hand drew a wonderful animation frame by frame as a reference and I set about trying to figure out how to make it work.

My first instinct was that this should exist as a custom view transition, but I spent a lot of time trying to figure out how to make that work and couldn’t get it right. I suspect I was missing something obvious, but I was running out of time and couldn’t spend any more time digging into it so I needed a different way.

I was also torn between deciding if I should find a way to translate all of the frames of Gedeon’s animation to code or just use the images he had already made and be done with it.

Given enough time I could have probably worked out a way to actually draw each of the shapes into an animated Canvas, but ultimately I gave up on that and built a flip book-style animation view powered by TimelineView to play a sequence of Image views.

I set up the flip book animation to play when it first appeared and then to update a binding when it was done which allowed me to overlay it on top of the normal heart button, play when it appeared, and then have it disappear when finished. I think it turned out pretty great!

Building Wallaroo in SwiftUI was quite an eye-opening experience for all of us. There were a lot of unexpected troubles along the way, but we worked through them and found solutions. There were certainly some problems that, in my opinion, would simply have never occurred had we built the app with UIKit – but that said, I’m not sure we would have completed the app in time for the launch of iOS 16 without SwiftUI.

While I ran into a lot difficulties that may or may not be bugs and spent a bunch of time trying to better understand the “right way” to do things for future reference, Craig was able to easily implement the entire set of settings screens, the purchasing flows, Patreon integration, and a bunch of other simple but important views without any significant problems – likely because they all better fit the types of things that SwiftUI was originally designed for in the first place.

In my opinion, a lot of the app’s ancillary views would have required far more code and time to build with UIKit and that’s an important point in favor of SwiftUI despite the occasional trouble in some corners.

I think it’s important to remember that our goal was to build an entire app which means dealing with a lot of the incidental stuff that SwiftUI makes trivial – like experimenting with different interactions, layouts, animations, and even whole view hierarchies. Making quick changes to those things in SwiftUI requires practically no code and absolutely no auto layout constraints, no management of delegates or controllers, and no subclassing all while adapting to different aspect ratios and accessibility settings with nearly no effort. (Plus you can see the changes as you type them if you have the previews set up!)

Clearly there are some blindspots in the framework that need to be addressed, but without trying to use it we could not have known where they were. Just because some parts of the app may have been less troublesome to implement had we used UIKit doesn’t mean SwiftUI itself is a failure or useless. Our new experience will hopefully allow us (and perhaps you) to better pick battles going forward. There’s no rule against using UIKit when necessary, after all – but ideally (in my opinion) we shouldn’t have to.

I hope you enjoyed this deep dive into the Wallaroo development process. For my part, I mostly liked working with SwiftUI once I started to get used to the way it works. There were certainly some points of deep frustration along the way, but in my experience that happens in every single project no matter what technologies are being used to develop it (yes, even UIKit). Unfortunately there will always be things that just don’t seem to work as well as you’d hoped. Maybe someday someone will create the one true holy grail of app development frameworks, but until then, we might as well play with what we’ve got.

Get Wallaroo from the App Store!

Wallaroo and SwiftUI (4 of 5)

September 22, 2022

By Sean Heber

In the last post, I talked about overcoming some issues with Wallaroo‘s main gallery view, but unexpectedly even the simple wallpaper detail screen held its share of challenges!

The biggest surprise for me was how much trouble I had implementing the paging view to swipe left and right between wallpaper variants. In UIKit it’s trivial to enable paged mode on a UIScrollView to get this behavior, but I couldn’t find a way to do it in SwiftUI for some reason. I ran across a bunch of tutorials that were manually implementing panning gestures and paging and I was flabbergasted. Did I really need to do all of this myself from scratch?

I tried a few different open source paging view implementations I found on GitHub but they were all lacking in one way or another.

The most glaring problem with them tended to be that the scrolling physics felt entirely wrong. The swipes didn’t have the same momentum that Apple uses everywhere else and the resistance on the rubber band effect (if it even had it) was never quite right. I started going down the road of adapting one of the better ones with more correct physics after I discovered this gem of a project which meticulously deconstructed the formulas necessary to get an Apple-like scroll view feeling. Still, though, nothing about this approach felt right.

Eventually I decided that maybe I should just wrap a UIScrollView to accomplish what we needed and started to dive into that.

I was pretty far into this when I accidentally stumbled across a Stack Overflow comment noting that SwiftUI actually does have a native paging view – it’s just cleverly hidden as a TabView style!

srsly?

OMFG.

I wasted most of a week on approaches to this before I managed to discover that, lo and behold, SwiftUI actually does have a way to do it – and it’s a single line of code: .tabViewStyle(.page).

I was supremely pissed off at myself for somehow missing this. Despite all of my searching, I never managed to notice any reference to it in the documentation and apparently didn’t remember anything about it from any of the WWDC videos I had watched, either. I suppose perhaps my search terms were too laced with an assumption that it’d be a part of ScrollView somehow or that it would exist as its own view?

I soon learned that SwiftUI didn’t always include support for a paging view – which is why there were so many outdated tutorials and open source projects out there for me to accidentally find instead of the official API. Argh.

SwiftUI changes so much every year and I can’t count the number of times I found an accepted Stack Overflow answer for a thing that was completely wrong as a result. (This is also true of Swift itself – although it’s getting better over time as they’ve become more resistant to source breaking changes.)

There’s also something off about how SwiftUI documentation is written and organized. It frequently feels next to impossible to find the name of whatever view modifier you might be needing unless you more or less already know what you’re looking for. To make matters worse, the fact that SwiftUI’s view modifiers almost all exist as function extensions on View means just pressing the period key and browsing autocompletion suggestions tells you nothing about what might or might not make sense to use in your current context.

The plethora of tutorials, Medium articles, YouTube videos, and books also mostly have a feeling of “magical thinking” to them – as if you just need to memorize incantations to spells rather than learn any of the actual science behind the effects you are trying to achieve. I find that aspect of the SwiftUI ecosystem extremely frustrating and disappointing.

All together these things make SwiftUI feel very difficult to learn and master.

So anyway, after discovering TabView‘s support for paging, I threw away everything I had been working on for a week and used it instead.

Unfortunately it is extremely buggy.

I don’t want to get in to every single problem I ran into with it or this blog series would be about three times longer than it is already, but suffice to say there were a lot. My source file has 6 different bullet points of issues I ran into!

Luckily I was able to workaround them all (one dumb issue was needing to wrap the TabView inside of a ScrollView with scrolling disabled in order to get it to stop jumping around when it first appeared which then of course ended up requiring a second workaround to fix an issue with that workaround…), but the worst, by far, was a memory leak/retain cycle!

We discovered the memory problem around the time I was working on the AsyncImage replacement I mentioned earlier. I had implemented various caching schemes for the images and I kept modifying my approach because it turned out the app was eating RAM and the most obvious culprit was the cache. In fact the initial reason I ripped most of the caching out and revisited it was in an attempt to hunt down this leak!

Unfortunately even with all caching removed I was still seeing a huge memory leak somewhere. I tried using Instruments to find it, but I had no luck deciphering where it was coming from – other than to see confirmation that memory was indeed leaking like crazy.

“Be a software developer,” they said.

I spent two days on this problem.

I don’t mean two work days – I mean pretty much two entire days stopping only for food and sleep.

I was trying everything I could think of to narrow it down. I first started by commenting out random stuff and manually running through the very long sequence of events I had found that could reliably consume the memory. Over… and over…. and over… (And over and over and over…)

Eventually I discovered (around 1am on the second day) that using a selection binding on the TabView was keeping the entire TabView instance alive somehow even when the view that contained it was destroyed.

So over time, after viewing a bunch of wallpapers and scrolling through the variants, all of those huge images were staying in memory even when you went back to the gallery view and loaded a different wallpaper! Slowly, with regular usage, the consumed memory climbed and climbed until iOS killed the app.

My paging view was its own standalone view that had a TabView inside of it. To expose the currently selected tab to the wallpaper details view, I passed in a binding which was in turn used by the TabView. Somehow, though, this is what was causing the problem because when I commented that part out, it wouldn’t leak – but I needed the selection binding to be passed along from the detail view to the inner TabView somehow!

On a whim I tried doing something more indirect and added a new state variable to the paging view which would hold the selection and passed that to the TabView as a binding instead. Then I used .onChanged to note when the selection state variable changed and updated the original binding that was passed into my wrapper view from outside. This appeared to break whatever retain cycle was happening.

I don’t know exactly why this worked (I can only speculate), but some part of my tired and sleepy brain thought to try it and it turned out to solve the issue in the end – but not without some pretty serious frustration and anger.

I feel like I should send Apple a bill for the pain and suffering I endured on this one.

Since this caused me so many problems, I decided that I would share my PagingView code to maybe save someone else some time or see if anyone has any better ideas. (And if we’re really lucky, maybe a SwiftUI engineer will see this and fix it!)

Now that this rather unexpected battle with the paging view was behind us, we were surely on the homestretch! Wallaroo was nearly fully functional – except for one minor detail