a rge size codeb a se will ever be a ble to fully a dopt Swift Concurrency Checking a nd Swift 6. I would a lso expect a short-term rise in concurrency bugs in iOS a pps.”
a rge size codeb a se will ever be a ble to fully a dopt Swift Concurrency Checking a nd Swift 6. I would a lso expect a short-term rise in concurrency bugs in iOS a pps.” “M a n, Swift 6 will be merciless on existing codeb a ses. I a dvise you to a dd -strict-concurrency=complete to your current Swift project a nd st a rt f ixing a w a y. Be prep a red.”
6 will be merciless on existing codeb a ses. I a dvise you to a dd -strict-concurrency=complete to your current Swift project a nd st a rt f ixing a w a y. Be prep a red.” “ I'm confused a bout concurrency a g a in, c a n you ple a se help?”
a “ I'm confused a bout concurrency a g a in, c a n you ple a se help?” “But is it something we need to be pushing on a ll iOS a pp developers? I know it’s option a l, but m a ny will not see it th a t w a y a nd will try to do everything they c a n to get their code b a se to Swift 6, even if th a t’s a t the cost of re a d a bility.”
a “ I'm confused a “But is it something we need to be pushing on a ll iOS a pp developers? I know it’s option a l, but m a ny will not see it th a t w a y a nd will try to do everything they c a n to get their code b a se to Swift 6, even if th a t’s a t the cost of re a d a bility.” “Swift 6 concurrency? Good luck ”
• 100% Swift 5.5+ code. • All UIKit + storybo a rds, using KiLS a rchitecture. • Core D a t a store. • 3 m a in b a ckend services sh a ring one OAuth 2 b a sed a uthoriz a tion service. • 8 a ddition a l d a t a sources which integr a te with the m a in 3. • Custom on-the- f ly tr a nsl a tion engine. • 17 extern a l dependencies, a ll SPM. • ~80k lines of Swift code • ~30k lines of XML • ~15k lines of JSON • ~8k lines of v a rious other a ssets (SVG, CSS, HTML etc)
protocol; this is a n error in the Swift 6 l a ngu a ge mode Sending 'model' risks c a using d a t a r a ces; this is a n error in the Swift 6 l a ngu a ge mode M a in a ctor-isol a ted property 'textContentType' c a n not be mut a ted from a nonisol a ted context; this is a n error in the Swift 6 l a ngu a ge mode C a ll to m a in a ctor-isol a ted inst a nce method 'register(_:withReuseIdenti f ier:)' in a synchronous nonisol a ted context; this is a n error in the Swift 6 l a ngu a ge mode C a pture of 'bestAttemptContent' with non-send a ble type 'UNMut a bleNoti f ic a tionContent' in a `@Send a ble` closure; this is a n error in the Swift 6 l a ngu a ge mode St a tic property 'utcD a teTimeForm a tter' is not concurrency-s a fe bec a use it is nonisol a ted glob a l sh a red mut a ble st a te; this is a n error in the Swift 6 l a ngu a ge mode Type 'CurrentTicketD a t a Source.GridItem' does not conform to the 'Send a ble' protocol; this is a n error in the Swift 6 l a ngu a ge mode
ve to a ddress a ll these issues in one sitting. If you h a ve to ship a rele a se, or go work on some more pressing ch a nge, you c a n go b a ck into Settings a nd turn strict checking b a ck o ff . All the ch a nges you m a de to reduce those w a rnings will be v a lid improvements to the code b a se th a t you c a n keep a nd check in, even if you then go b a ck to minim a l checking for a while. You c a n return to [strict checking] l a ter when you’re re a dy, a nd t a ckle them then.” – Migrate your app to Swift 6 · WWDC24
a ve. Every one. Compiler will then immedi a tely tell you if some of those model types c a n’t be send a ble a nd why, which is a n opportunity to think-through the us a ge of th a t speci f ic model type.
end of the tr a nsition. The w a rnings will keep bugging you but over time, a s you upd a te the a pp, you h a ve a gre a ter ch a nce to a void @unchecked entirely.
bout it. If you end in a situ a tion where your model type should potenti a lly be a n a ctor you a re likely m a king a serious a rchitectur a l / design p a ttern mist a ke.
priv a te seri a l queue. It m a kes code more re a d a ble but does not s a ve you from r a ce conditions. Reentr a ncy is very re a l a nd super h a rd problem.
in of methods where a t le a st one method is async ⇥ convert entire ch a in to be async except the f irst method in the ch a in. - In other words: keep the us a ge of Task{} a t minimum.
a s c a ught a bunch of mist a kes I m a de. • I m a de a couple of mist a kes trying to speed run f ixes. • Some of the solutions to the problems a re h a rder to gr a sp th a n I hoped. • Wish there w a s a “sure you a re correct but I c a n gu a r a ntee this a in’t ever going to h a ppen, let me do it” – Miguel de Icaza
a in a pp a nd s a ve them loc a lly • cre a te Tr a nsl a tions p a ck a ge th a t re a ds th a t loc a l f ile • a lso exposes public MBLocalizedString() method • a dd Tr a nsl a tions a s dependency to a ll other p a ck a ges a nd the m a in a pp Proper solution
a iting, rendering a bit more, a w a iting something else… Alw a ys f irst a w a it a ll the d a t a you need a nd then st a rt rendering in one uninterrupted sequence of synchronous code. Nightmare fodder
ses prob a bility for r a ce conditions. Full-on concurrency will cert a inly reve a l even the sm a llest logic a l errors, prem a ture f l a g checks a nd toggles etc. Nightmare fodder
{ do { // fetch account state try await fetchCurrentAccount(flowIdentifier: fid) // fetch active promotion progress try await fetchActivePromotionProgress(flowIdentifier: fid) // fetch KPI try await fetchAccountKPI(andAnnounce: notify, flowIdentifier: fid) // check if there are player limits setup and possibly reached await postLoginPlayerLimitsCheck(flowIdentifier: fid) // setup session limit if there is one configured on this account setupSessionTimer(flowIdentifier: fid) // do we have any pending notifications (done here to update badge on profile icon) try await fetchPendingAtlasNotifications(flowIdentifier: fid) try await fetchAtlasNotificationsHistory(flowIdentifier: fid) // continuous periodical update setupAtlasNotificationsTimer() // continuous periodical update setupBalanceTimer() } catch let err { log(level: .warning, flowIdentifier: fid, String(reflecting: err)) } } Horribly wrong piece of code
longer. Swift 6 obsoleted quite a bit of work th a t w a s necess a ry only for 5.10. I tend to think of this rele a se more like Concurrency 1.0. – Matthew Massicotte
tion, which w a s by f a r the most time consuming p a rt. • It m a de the code w a y more re a d a ble a nd extend a ble. • It forced us to re-think a nd re-do m a ny h a cks a nd question a ble shortcuts we h a d in the code. • Eventu a lly m a de the a pp more st a ble.
a se a nd is f ine. We en a ble it in the modules we c a n (th a t we were re a dy for, during Swift 5 d a ys which is gre a t), on some is en a bled but with a couple of uns a fe a nd the rest is in 5 a nd f ine. I feel like people a re being overdr a m a tic a bout Swift 6 concurrency. Is a n option a l mode, it c a n be en a bled by module a nd there a re uns a fe opt outs. I honestly think the Swift te a m went f a r a nd beyond to m a ke this a good tr a nsition. Is it perfect? No. But I don't see the dr a m a . – Alejandro Martinez