{"id":674,"date":"2023-02-06T14:00:42","date_gmt":"2023-02-06T14:00:42","guid":{"rendered":"https:\/\/fde.cat\/index.php\/2023\/02\/06\/the-evolution-of-facebooks-ios-app-architecture\/"},"modified":"2023-02-06T14:00:42","modified_gmt":"2023-02-06T14:00:42","slug":"the-evolution-of-facebooks-ios-app-architecture","status":"publish","type":"post","link":"https:\/\/fde.cat\/index.php\/2023\/02\/06\/the-evolution-of-facebooks-ios-app-architecture\/","title":{"rendered":"The evolution of Facebook\u2019s iOS app architecture"},"content":{"rendered":"<p><span>Facebook for iOS (FBiOS) is the oldest mobile codebase at Meta. <\/span><a href=\"https:\/\/engineering.fb.com\/2012\/08\/23\/ios\/under-the-hood-rebuilding-facebook-for-ios\/\" target=\"_blank\" rel=\"noopener\"><span>Since the app was rewritten in 2012<\/span><\/a><span>, it has been worked on by thousands of engineers and shipped to billions of users, and it can support hundreds of engineers iterating on it at a time.<\/span><\/p>\n<p><span><a href=\"https:\/\/engineering.fb.com\/2012\/08\/23\/ios\/under-the-hood-rebuilding-facebook-for-ios\/\" target=\"_blank\" rel=\"noopener\">After years of iteration<\/a>, the Facebook codebase does not resemble a typical iOS codebase:<\/span><\/p>\n<p><span>It\u2019s full of C++, Objective-C(++), and Swift.<\/span><br \/>\n<span>It has dozens of <a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/DeveloperTools\/Conceptual\/DynamicLibraries\/100-Articles\/UsingDynamicLibraries.html\" target=\"_blank\" rel=\"noopener\">dynamically loaded libraries (dylibs)<\/a>, and so many classes that they can\u2019t be loaded into Xcode at once.<\/span><br \/>\n<span>There is almost zero raw usage of Apple\u2019s SDK \u2014 everything has been wrapped or replaced by an in-house abstraction.<\/span><br \/>\n<span>The app makes heavy use of code generation, spurred by <a href=\"https:\/\/www.buck.build\/\" target=\"_blank\" rel=\"noopener\">Buck<\/a>, our <\/span><span>custom build system<\/span><span>.<\/span><br \/>\n<span>Without heavy caching from our build system, engineers would have to spend an entire workday waiting for the app to build.<\/span><\/p>\n<p><span>FBiOS was never intentionally architected this way. The app\u2019s codebase reflects 10 years of <\/span><span>evolution<\/span><span>, spurred by technical decisions necessary to support the growing number of engineers working on the app, its stability, and, above all, the user experience.<\/span><\/p>\n<p><span>Now, to celebrate the codebase\u2019s 10-year anniversary, we\u2019re shedding some light on the technical decisions behind this evolution, as well as their historical context.<\/span><\/p>\n<h2><span>2014: Establishing our own mobile frameworks<\/span><\/h2>\n<p><span>Two years after Meta <\/span><a href=\"https:\/\/engineering.fb.com\/2012\/08\/23\/ios\/under-the-hood-rebuilding-facebook-for-ios\/\" target=\"_blank\" rel=\"noopener\"><span>launched the native rewrite of the Facebook app<\/span><\/a><span>, News Feed\u2019s codebase began to have reliability issues. At the time, News Feed\u2019s data models were backed by Apple\u2019s default framework for managing data models: <\/span><a href=\"https:\/\/developer.apple.com\/documentation\/coredata?language=objc\" target=\"_blank\" rel=\"noopener\"><span>Core Data<\/span><\/a><span>. Objects in Core Data are mutable, and that did not lend itself well to News Feed\u2019s multithreaded architecture. To make matters worse, News Feed utilized bidirectional data flow, stemming from its use of Apple\u2019s de facto design pattern for Cocoa apps: <\/span><a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/General\/Conceptual\/DevPedia-CocoaCore\/MVC.html\" target=\"_blank\" rel=\"noopener\"><span>Model View Controller<\/span><\/a><span>.<\/span><\/p>\n<p><span>Ultimately, this design exacerbated the creation of nondeterministic code that was very difficult to debug or reproduce bugs. It was clear that this architecture was not sustainable and it was time to rethink it.<\/span><\/p>\n<p><span>While considering new designs, one engineer investigated <\/span><a href=\"https:\/\/reactjs.org\/\"><span>React<\/span><\/a><span>, Facebook\u2019s (open source) UI framework, which was becoming quite popular in the Javascript community. React\u2019s declarative design abstracted away the tricky imperative code that caused issues in Feed (on web), and leveraged a one-way data flow, which made the code much easier to reason about. These characteristics seemed well suited for the problems News Feed was facing. There was only one problem.<\/span><\/p>\n<p><span>There was no declarative UI in Apple\u2019s SDK.\u00a0<\/span><\/p>\n<p><a href=\"https:\/\/developer.apple.com\/swift\/blog\/?id=14\" target=\"_blank\" rel=\"noopener\"><span>Swift wouldn\u2019t be announced for a few months<\/span><\/a><span>, and SwiftUI (Apple\u2019s declarative UI framework) wouldn\u2019t be announced until 2019. If News Feed wanted to have a declarative UI, the team would have to build a new UI framework.\u00a0<\/span><\/p>\n<p><span>Ultimately, that\u2019s what they did.<\/span><\/p>\n<p><span>After spending a few months building and migrating News Feed to run on a new declarative UI and a new data model, <\/span><a href=\"https:\/\/engineering.fb.com\/2014\/10\/31\/ios\/making-news-feed-nearly-50-faster-on-ios\/\" target=\"_blank\" rel=\"noopener\"><span>FBiOS saw a 50 percent performance improvement<\/span><\/a><span>. A few months later, they open-sourced their React-inspired UI framework for mobile, <\/span><a href=\"https:\/\/engineering.fb.com\/2015\/03\/25\/ios\/introducing-componentkit-functional-and-declarative-ui-on-ios\/\" target=\"_blank\" rel=\"noopener\"><span>ComponentKit<\/span><\/a><span>.\u00a0<\/span><\/p>\n<p><span>To this day, ComponentKit is still the de facto choice for building native UIs in Facebook. It has provided <\/span><span>countless<\/span><span> performance improvements to the app via view reuse pools, view flattening, and background layout computation. It also inspired its Android counterpart, <\/span><a href=\"https:\/\/engineering.fb.com\/2018\/01\/31\/android\/improving-android-video-on-news-feed-with-litho\/\" target=\"_blank\" rel=\"noopener\"><span>Litho<\/span><\/a><span>, and SwiftUI.<\/span><\/p>\n<p><span>Ultimately, the choice to replace the UI and data layer with custom infra was a trade-off. To achieve a delightful user experience that could be reliability maintained, new employees would have to shelve their industry knowledge of Apple APIs to learn the custom in-house infra.\u00a0<\/span><\/p>\n<p><span>This wouldn\u2019t be the last time FBiOS would have to make a decision that balanced end user experience with developer experience and speed. Going into 2015, the app\u2019s success would trigger what we refer to as a feature explosion. And that presented its own set of unique challenges.<\/span><\/p>\n<h2><span>2015: An architectural inflection point<\/span><\/h2>\n<p><span>By 2015, Meta had doubled down on its <\/span><a href=\"https:\/\/www.reuters.com\/article\/net-us-facebook-roadshow\/facebooks-zuckerberg-says-mobile-first-priority-idUSBRE84A18520120512\" target=\"_blank\" rel=\"noopener\"><span>\u201cMobile First\u201d mantra<\/span><\/a><span>, and the FBiOS codebase saw a meteoric rise in the number of daily contributors. As more and more products were integrated into the app, its launch time began to degrade, and people began to notice. Toward the end of 2015, startup performance was so slow (nearly 30 seconds!) that it risked being killed by the phone\u2019s OS.<\/span><\/p>\n<p><span>Upon investigation, it was clear that there were many<\/span> <span>contributing factors to degraded startup performance. For the sake of brevity, we\u2019ll focus only on the ones that had a long-term effect on the app\u2019s architecture:<\/span><\/p>\n<p><span>The app\u2019s \u2018pre-main\u2019 time was growing at an unbounded rate, as the app\u2019s size grew with each product.<\/span><br \/>\n<span>The app\u2019s \u2018module\u2019 system gave each product ungoverned access to all the app\u2019s resourcing. This led to a <\/span><a href=\"https:\/\/en.wikipedia.org\/wiki\/Tragedy_of_the_commons\" target=\"_blank\" rel=\"noopener\"><span>tragedy of the commons issue<\/span><\/a><span> as each product leveraged its \u2018hook\u2019 into startup to perform computationally expensive operations so that initial navigation to that product would be snappy.<\/span><\/p>\n<p><span>The changes that were needed to mitigate and improve startup would fundamentally alter the way product engineers wrote code for FBiOS.<\/span><\/p>\n<h2><span>2016: Dylibs and modularity<\/span><\/h2>\n<p><span>According to Apple\u2019s wiki about <\/span><a href=\"https:\/\/developer.apple.com\/documentation\/xcode\/reducing-your-app-s-launch-time\" target=\"_blank\" rel=\"noopener\"><span>improving launch times<\/span><\/a><span>, a number of operations have to be performed before an app\u2019s \u2018main\u2019 function can be called. Generally, the more code an app has, the longer this will take.<\/span><\/p>\n<p><span>While \u2018pre-main\u2019 contributed only a small subset of the 30 seconds being spent during launch, it was a particular concern because it would continue to grow at an unbounded rate as FBiOS continued to amass new features.<\/span><\/p>\n<p><span>To help mitigate the unbounded growth of the app\u2019s launch time, our engineers began to move large swaths of product code into a lazily loaded container known as a dynamic library (<\/span><a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/DeveloperTools\/Conceptual\/DynamicLibraries\/100-Articles\/UsingDynamicLibraries.html\" target=\"_blank\" rel=\"noopener\"><span>dylib<\/span><\/a><span>). When code is moved into a dynamically loaded library, it isn\u2019t required to load before the app\u2019s main() function.<\/span><\/p>\n<p><span>Initially, the FBiOS dylib structure looked like this:<\/span><\/p>\n\n<p><span>Two product dylibs (FBCamera and NotOnStartup) were created, and a third dylib (FBShared) was used to share code between the various dylibs and the main app\u2019s binary.<\/span><\/p>\n<p><span>The dylib solution worked beautifully. FBiOS was able to curb the unbounded growth of the app\u2019s startup time. As the years went by, most code would end up in a dylib so that startup performance stayed fast and was unaffected by the constant fluctuation of added or removed products in the app.<\/span><\/p>\n<p><span>The addition of dylibs triggered a mental shift in the way Meta\u2019s product engineers wrote code. With the addition of dylibs, runtime APIs like <\/span><span>NSClassFromString()<\/span><span> risked runtime failures because the required class lived in unloaded dylibs. Since many of the FBiOS core abstractions were built on <\/span><span>iterating through all the classes in memory<\/span><span>, FBiOS had to rethink how many of its core systems worked.<\/span><\/p>\n<p><span>Aside from the runtime failures, dylibs also introduced a new class of linker errors. In the event the code in Facebook (the startup set) referenced code in a dylib, engineers would see a linker error like this:<\/span><\/p>\n<p>Undefined symbols for architecture arm64:<br \/>\n  &#8220;_OBJC_CLASS_$_SomeClass&#8221;, referenced from:<br \/>\n      objc-class-ref in libFBSomeLibrary-9032370.a(FBSomeFile.mm.o)<\/p>\n<p><span>To fix this, engineers were required to wrap their code with a special function that could load a dylib if necessary:<\/span><\/p>\n<p><span>Suddenly:<\/span><\/p>\n<p>int main() {<br \/>\n  DoSomething(context);<br \/>\n}<\/p>\n<p>Would look like this:<\/p>\n<p>int main() {<br \/>\n  FBCallFunctionInDylib(<br \/>\n    NotOnStatupFramework,<br \/>\n    DoSomething,<br \/>\n    context<br \/>\n  );<br \/>\n}<\/p>\n<p><span>The solution worked, but had quite a few code smells:<\/span><\/p>\n<p><span>The <\/span><span>app-specific<\/span><span> dylib enum was hard-coded into various callsites. All apps at Meta had to share a dylib enum, and it was the reader\u2019s responsibility to determine whether that dylib was used by the app the code was running in.<\/span><br \/>\n<span>If the wrong dylib enum was used, the code would fail, but only at runtime. Given the sheer amount of code and features in the app, this late signal led to a lot of frustration during development.<\/span><\/p>\n<p><span>On top of all that, our only system to safeguard against the introduction of these calls during startup was runtime-based, and many releases were delayed while last-minute regressions were introduced into the app.<\/span><\/p>\n<p><span>Ultimately, the dylib optimization curbed the unbounded growth of the app\u2019s launch time, but it signified a massive inflection point in the way the app was architected. FBiOS engineers would spend the next few years re-architecting the app to smooth some of the rough edges introduced by the dylibs, and we (eventually) shipped an app architecture that was more robust than ever before.<\/span><\/p>\n<h2><span>2017: Rethinking the FBiOS architecture<\/span><\/h2>\n<p><span>With the introduction of dylibs, a few key components of FBiOS had to be rethought:<\/span><\/p>\n<p><span>The \u2018module registration system\u2019 could no longer be runtime-based.<\/span><br \/>\n<span>Engineers needed a way to know whether <\/span><span>any<\/span><span> codepath during startup could trigger a dylib load.<\/span><\/p>\n<p><span>To address these issues, FBiOS turned to Meta\u2019s open source build system, <\/span><a href=\"https:\/\/www.buck.build\/\" target=\"_blank\" rel=\"noopener\"><span>Buck<\/span><\/a><span>.<\/span><\/p>\n<p><span>Within Buck, each \u2018target\u2019 (app, dylib, library, etc.) is declared with some configuration, like so:<\/span><\/p>\n<p>apple_binary(<br \/>\n  name = &#8220;Facebook&#8221;,<br \/>\n  &#8230;<br \/>\n  deps = [<br \/>\n    &#8220;:NotOnStartup#shared&#8221;,<br \/>\n    &#8220;:FBCamera#shared&#8221;,<br \/>\n  ],<br \/>\n)<\/p>\n<p>apple_library(<br \/>\n  name = &#8220;NotOnStartup&#8221;,<br \/>\n  srcs = [<br \/>\n    &#8220;SomeFile.mm&#8221;,<br \/>\n  ],<br \/>\n  labels = [&#8220;special_label&#8221;],<br \/>\n  deps = [<br \/>\n    &#8220;:PokesModule&#8221;,<br \/>\n    &#8230;<br \/>\n  ],<br \/>\n)<\/p>\n<p><span>Each \u2018target\u2019 lists all information needed to build it (dependencies, compiler flags, sources, etc.), and when \u2018buck build\u2019 is called, it builds all this information into a graph that can be queried.<\/span><\/p>\n<p>$ buck query \u201cdeps(:Facebook)\u201d<br \/>\n&gt; :NotOnStartup<br \/>\n&gt; :FBCamera<\/p>\n<p>$ buck query \u201cattrfilter(labels, special_label, deps(:Facebook))\u201d<br \/>\n&gt; :NotOnStartup<\/p>\n<p><span>Using this core concept (and some special sauce), FBiOS began to produce some buck queries that could generate a holistic view of the classes and functions in the app during build. This information would be the building block of the app\u2019s next generation of architecture.<\/span><\/p>\n<h2><span>2018: The proliferation of generated code<\/span><\/h2>\n<p><span>Now that FBiOS was able to leverage Buck to query for information about code in the dependency, it could create a mapping of \u201cfunction\/classes -&gt; dylibs\u201d that could be generated on the fly.<\/span><\/p>\n<p>{<br \/>\n  &#8220;functions&#8221;: {<br \/>\n    &#8220;DoSomething&#8221;: Dylib.NotOnStartup,<br \/>\n    &#8230;<br \/>\n  },<br \/>\n  &#8220;classes&#8221;: {<br \/>\n    &#8220;FBSomeClass&#8221;: Dylib.SomeOtherOne<br \/>\n  }<br \/>\n}<\/p>\n<p><span>Using that mapping as input, FBiOS used it to generate code that abstracted away the dylib enum from callsites:<\/span><\/p>\n<p>static std::unordered_map&lt;const char *, Dylib&gt; functionToDylib {{<br \/>\n  { &#8220;DoSomething&#8221;, Dylib.NotOnStartup },<br \/>\n  { &#8220;FBSomeClass&#8221;, Dylib.SomeOtherOne },<br \/>\n  &#8230;<br \/>\n}};<\/p>\n<p><span>Using code generation was appealing for a few reasons:<\/span><\/p>\n<p><span>Because the code was regenerated based on local input, there was nothing to check in, and there were no more merge conflicts! Given that the engineering body of FBiOS could double every year, this was a big development efficiency win.<\/span><br \/>\n<span>FBCallFunctionInDylib no-longer required an app-specific dylib (and thus could be renamed to \u2018FBCallFunction\u2019). Instead, the call would read from static mapping generated for each application during build.<\/span><\/p>\n<p><span>Combining Buck query with code generation proved to be so successful that FBiOS used it as bedrock for a new plugin system, which eventually replaced the runtime-based app-module system.<\/span><\/p>\n<h3><span>Moving signal to the left<\/span><\/h3>\n<p><span>With the new Buck-powered plugin system. FBiOS was able to replace most runtime failures with build-time warnings by migrating bits of infra to a plugin-based architecture.<\/span><\/p>\n<p><span>When FBiOS is built, Buck can produce a graph to show the location of all the plugins in the app, like so:<\/span><\/p>\n\n<p><span>From this vantage point, the plugin system can surface build-time errors for engineers to warn:\u00a0<\/span><\/p>\n<p><span>\u201cPlugin D, E could trigger a load of a dylib. This is not allowed, since the caller of these plugins lives in the app\u2019s startup path.\u201d<\/span><br \/>\n<span>\u201cThere is no plugin for rendering Profiles found in the app \u2026 this means that navigating to that screen will not work.\u201d<\/span><br \/>\n<span>\u201cThere are two plugins for rendering Groups (Plugin A, Plugin B). One of them should be removed.\u201d<\/span><\/p>\n<p><span>With the old app module system, these errors would be \u201clazy\u201d runtime assertions. Now, engineers are confident that when FBiOS is built successfully, it won\u2019t fail because of missing functionality, dylibs loading during app startup, or invariants in the module runtime system.<\/span><\/p>\n<h3><span>The cost of code generation<\/span><\/h3>\n<p><span>While migrating FBiOS to a plugin system has improved the app\u2019s reliability, provided faster signals to engineers, and made it possible for the app to trivially share code with our other mobile apps, it came at a cost:<\/span><\/p>\n<p><span>Plugin errors are not on Stack Overflow and can be confusing to debug.<\/span><br \/>\n<span>A plugin system based on code generation and Buck is a far cry from traditional iOS development.\u00a0<\/span><br \/>\n<span>Plugins introduce a layer of indirection to the codebase. Where most apps would have a registry file with all features, these are generated in FBiOS and can be surprisingly difficult to find.<\/span><\/p>\n<p><span>There is no doubt that plugins led FBiOS farther away from idiomatic iOS development, but the trade-offs seem to be worth it. Our engineers can change code used in <\/span><span>many<\/span><span> apps at Meta and be sure that if the plugin system is happy, no app should crash because of missing functionality in a rarely tested codepath. Teams like News Feed and Groups can build an extension point for plugins and be sure that product teams can integrate into their surface without touching the core code.<\/span><\/p>\n<h2><span>2020: Swift and language architecture<\/span><\/h2>\n<p><span>While most of this article has focused on architectural changes stemming from scale issues in the Facebook app, changes in Apple\u2019s SDK have also forced FBiOS to rethink some of its architectural decisions.<\/span><\/p>\n<p><span>In 2020, FBiOS began to see a rise in the number of Swift-only APIs from Apple and a growing sentiment for more Swift in the codebase. It was finally time to reconcile with the fact that Swift was an inevitable tenant in FB apps.\u00a0<\/span><\/p>\n<p><span>Historically, FBiOS had used C++ as a lever to build abstraction, which saved on code size because of <\/span><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/Zero-overhead_principle\"><span>C++\u2019s zero overhead principle<\/span><\/a><span>. But C++ does not interop with Swift (yet). For <\/span><span>most<\/span><span> FBiOS APIs (like ComponentKit), some kind of shim would have to be created to use in Swift \u2014 creating code bloat.<\/span><\/p>\n<p><span>Here\u2019s a diagram outlining the issues in the codebase:<\/span><\/p>\n\n<p><span>With this in mind, we began to form a language strategy about when and where various bits of code should be used:<\/span><\/p>\n\n<p><span>Ultimately, the FBiOS team began to advise that product-facing APIs\/code should not contain C++ so that we could freely use Swift and future Swift APIs from Apple. Using plugins, FBiOS could abstract away C++ implementations so that they still powered the app but were hidden from most engineers.<\/span><\/p>\n<p><span>This type of workstream signified a bit of shift in the way FBiOS engineers thought about building abstractions. Since 2014, some of the biggest factors in framework building have been contributions to app size and expressiveness (which is why ComponentKit chose Objective-C++ over Objective-C).<\/span><\/p>\n<p><span>The addition of Swift was the first time these would take a backseat to developer efficiency, and we expect to see more of that in the future.<\/span><\/p>\n<h2><span>2022: The journey is 1 percent\u00a0 finished<\/span><\/h2>\n<p><span>Since 2014, FBiOS architecture has shifted quite a bit:<\/span><\/p>\n<p><span>It introduced countless in-house abstractions, like ComponentKit and GraphQL.<\/span><br \/>\n<span>It uses dylibs to keep \u2018pre-main\u2019 times minimal and contribute to a blazing-fast app startup.<\/span><br \/>\n<span>It introduced a plugin system (powered by Buck) so that dylibs are abstracted away from engineers, and so code is easily shareable between apps.<\/span><br \/>\n<span>It introduced language guidelines about when and where various languages should be used and began to shift the codebase to reflect those language guidelines.<\/span><\/p>\n<p><span>Meanwhile, Apple has introduced exciting improvements to their phones, OS, and SDK:<\/span><\/p>\n<p><span>Their new phones are <\/span><span>fast<\/span><span>. The cost of loading is much smaller than it was before.<\/span><br \/>\n<span>OS improvements like dyld3 and chain fixups provide software to make code loading even faster.<\/span><br \/>\n<span>They\u2019ve introduced SwiftUI,\u00a0 a declarative API for UI that shares a lot of concepts with ComponentKit.<\/span><br \/>\n<span>They\u2019ve provided improved SDKs, as well as APIs (like interruptible animations in iOS8) that we could have built custom frameworks for.<\/span><\/p>\n<p><span>As more experiences are shared across Facebook, Messenger, Instagram, and WhatsApp, FBiOS is revisiting all these optimizations to see where it can move closer to platform orthodoxy. Ultimately, we\u2019ve seen that the easiest ways to share code are to use something that the app gives you for free or build something that is virtually dependency-free and can integrate between all the apps.<\/span><\/p>\n<p><span>We\u2019ll see you back here in 2032 for the recap of the codebase\u2019s 20-year anniversary!<\/span><\/p>\n<p>The post <a href=\"https:\/\/engineering.fb.com\/2023\/02\/06\/ios\/facebook-ios-app-architecture\/\">The evolution of Facebook\u2019s iOS app architecture<\/a> appeared first on <a href=\"https:\/\/engineering.fb.com\/\">Engineering at Meta<\/a>.<\/p>\n<p>Engineering at Meta<\/p>","protected":false},"excerpt":{"rendered":"<p>Facebook for iOS (FBiOS) is the oldest mobile codebase at Meta. Since the app was rewritten in 2012, it has been worked on by thousands of engineers and shipped to billions of users, and it can support hundreds of engineers iterating on it at a time. After years of iteration, the Facebook codebase does not&hellip; <a class=\"more-link\" href=\"https:\/\/fde.cat\/index.php\/2023\/02\/06\/the-evolution-of-facebooks-ios-app-architecture\/\">Continue reading <span class=\"screen-reader-text\">The evolution of Facebook\u2019s iOS app architecture<\/span><\/a><\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":""},"categories":[7],"tags":[],"class_list":["post-674","post","type-post","status-publish","format-standard","hentry","category-technology","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":302,"url":"https:\/\/fde.cat\/index.php\/2021\/08\/31\/a-brief-history-of-rust-at-facebook\/","url_meta":{"origin":674,"position":0},"title":"A brief history of Rust at Facebook","date":"August 31, 2021","format":false,"excerpt":"Facebook is embracing Rust, one of the most loved and fastest-growing programming languages available today. In addition to bringing new talent to its Rust team, Facebook has announced that it is officially joining the nonprofit Rust Foundation. Alongside fellow members including Mozilla (the creators of Rust), AWS, Microsoft, and Google,\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":762,"url":"https:\/\/fde.cat\/index.php\/2023\/09\/12\/slack-behind-the-scenes-overcoming-key-challenges-to-craft-a-seamless-mobile-app\/","url_meta":{"origin":674,"position":1},"title":"Slack Behind the Scenes: Overcoming Key Challenges to Craft a Seamless Mobile App","date":"September 12, 2023","format":false,"excerpt":"By Tracy Stampfli and Scott Nyberg In our \u201cEngineering Energizers\u201d Q&A series, we examine the professional life experiences that have shaped Salesforce Engineering leaders. Meet Tracy Stampfli, a Principal Software Engineer for Slack at Salesforce. Tracy works behind the scenes on Slack\u2019s mobile infrastructure team \u2014 an elite group of\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":492,"url":"https:\/\/fde.cat\/index.php\/2021\/10\/20\/facebook-engineers-receive-2021-ieee-computer-society-cybersecurity-award-for-static-analysis-tools\/","url_meta":{"origin":674,"position":2},"title":"Facebook engineers receive 2021 IEEE Computer Society Cybersecurity Award for static analysis tools","date":"October 20, 2021","format":false,"excerpt":"Until recently, static analysis tools weren\u2019t seen by our industry as a reliable element of securing code at scale. After nearly a decade of investing in refining these systems, I\u2019m so proud to celebrate our engineering teams today for being awarded the IEEE Computer Society\u2019s Cybersecurity Award for Practice for\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":742,"url":"https:\/\/fde.cat\/index.php\/2023\/08\/07\/fixit-2-metas-next-generation-auto-fixing-linter\/","url_meta":{"origin":674,"position":3},"title":"Fixit 2: Meta\u2019s next-generation auto-fixing linter","date":"August 7, 2023","format":false,"excerpt":"Fixit is dead! Long live Fixit 2 \u2013 the latest version of our open-source auto-fixing linter. Fixit 2 allows developers to efficiently build custom lint rules and perform auto-fixes for their codebases. Fixit 2 is available today on PyPI. Python is one of the most popular languages in use at\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":480,"url":"https:\/\/fde.cat\/index.php\/2021\/09\/29\/open-sourcing-mariana-trench-analyzing-android-and-java-app-security-in-depth\/","url_meta":{"origin":674,"position":4},"title":"Open-sourcing Mariana Trench: Analyzing Android and Java app security in depth","date":"September 29, 2021","format":false,"excerpt":"We\u2019re sharing details about Mariana Trench (MT), a tool we use to spot and prevent security and privacy bugs in Android and Java applications. As part of our effort to help scale security through building automation, we recently open-sourced MT to support security engineers at Facebook and across the industry.\u00a0\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":575,"url":"https:\/\/fde.cat\/index.php\/2022\/05\/09\/language-packs-metas-mobile-localization-solution\/","url_meta":{"origin":674,"position":5},"title":"Language packs: Meta\u2019s mobile localization solution","date":"May 9, 2022","format":false,"excerpt":"More than 3 billion people around the world rely on our services each month. On mobile, around 57 percent of people on Facebook for Android and 49 percent of those on Facebook for iOS use the app in a language other than English. Delivering the best experience for these people,\u2026","rel":"","context":"In &quot;Technology&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/posts\/674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/comments?post=674"}],"version-history":[{"count":0,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/posts\/674\/revisions"}],"wp:attachment":[{"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/media?parent=674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/categories?post=674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fde.cat\/index.php\/wp-json\/wp\/v2\/tags?post=674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}