<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: German</title>
    <description>The latest articles on DEV Community by German (@germanxp).</description>
    <link>https://dev.to/germanxp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1044957%2Fb2b25a23-fb4b-4e97-85f6-99b050990548.jpeg</url>
      <title>DEV Community: German</title>
      <link>https://dev.to/germanxp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/germanxp"/>
    <language>en</language>
    <item>
      <title>Light up your SwiftUI TabView</title>
      <dc:creator>German</dc:creator>
      <pubDate>Mon, 27 Mar 2023 10:53:07 +0000</pubDate>
      <link>https://dev.to/germanxp/light-up-your-swiftui-tabview-2ln8</link>
      <guid>https://dev.to/germanxp/light-up-your-swiftui-tabview-2ln8</guid>
      <description>&lt;p&gt;In SwiftUI, the &lt;code&gt;TabView&lt;/code&gt; APIs and customization is somewhat limited. We can often see tutorials and articles on how to create custom tab view components replicating similar layouts and behaviors. This time I want to show you very simple explorations I did last night with the native &lt;code&gt;TabView&lt;/code&gt; component that will add some sparks to your app.&lt;/p&gt;

&lt;p&gt;The code is super simple, let's start with a basic &lt;code&gt;TabView&lt;/code&gt; layout in SwiftUI within our main view's body.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var body: some View {
  TabView(selection: $selectedTab) {
        FirstScreen()
          .tabItem {
            Image(systemName: "1.circle.fill")
            Text("First tab")
          }
          .tag(RootTab.first)
        SecondScreen()
          .tabItem {
            Image(systemName: "2.circle.fill")
            Text("Second tab")
          }
          .tag(RootTab.second)
        ThirdScreen()
          .tabItem {
            Image(systemName: "3.circle.fill")
            Text("Third tab")
          }
          .tag(RootTab.third)
      }
      .background(Color.secondary)
      .tint(.red)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A couple of things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are using the initializer of &lt;code&gt;TabView&lt;/code&gt; that receives a Binding for the selected value. We will use it later also, but for now, we will declare a @State var in our host view:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@State private var selectedTab: RootTab = .second
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This is how it looks the RootTab enum, but you can basically use you own typed tabs.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;internal enum RootTab: Int {
  case first, second, third

  /// We use this to color the light of each tab when selected.
  var selectionColor: Color {
    switch self {
    case .first, .third:
      return .purple
    case .second:
      return .main
    }
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, this is the standard look and feel of the &lt;code&gt;TabView&lt;/code&gt;, which doesn't bring that much joy :(&lt;/p&gt;

&lt;p&gt;The idea is to add a light that focuses on the selected tab, and changes when the user switches to other tabs. For that, let's use an overlay modifier in out &lt;code&gt;TabView&lt;/code&gt; like follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TabView() {...}
  .overlay(alignment: .bottom) {
        let color = selectedTab.selectionColor
        GeometryReader { geometry in
          let aThird = geometry.size.width / 3
          VStack {
            Spacer()
            Circle()
              .background(color.blur(radius: 20))
              .frame(width: aThird, height: 30)
              .shadow(color: color, radius: 40)
              .offset(
                x: CGFloat(selectedTab.rawValue) * aThird,
                y: 30
              )
          }
        }
      }
      .edgesIgnoringSafeArea(.bottom)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How does it work?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The overlay adds a &lt;code&gt;Circle&lt;/code&gt; shape on top of our &lt;code&gt;TabView&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We style the circle to have a shadow with big blur value that will simulate the light in the selected tab. &lt;/li&gt;
&lt;li&gt;The background modifier doesn't really need to be a blurred color but it enhanced the &lt;code&gt;light&lt;/code&gt; effect a bit. You can play around and see how it works for you.&lt;/li&gt;
&lt;li&gt;We set the width of the &lt;code&gt;Circle&lt;/code&gt; to third of the screen's width by using a &lt;code&gt;GeometryReader&lt;/code&gt; to get the size of the &lt;code&gt;TabView&lt;/code&gt;. The height is up to you but it changes the strength of the shadow so again, play around to get the best results.&lt;/li&gt;
&lt;li&gt;Then we use an offset modifier to position the &lt;code&gt;Circle&lt;/code&gt; shape, this allow us to position the shape itself below the &lt;code&gt;TabView&lt;/code&gt; and letting only the shadow portion visible.&lt;/li&gt;
&lt;li&gt;The horizontal offset(x axis), will be updated when the &lt;code&gt;selectedTab&lt;/code&gt; changes, so the light &lt;code&gt;moves&lt;/code&gt; when the user switches tabs.&lt;/li&gt;
&lt;li&gt;Last, but no least, the &lt;code&gt;edgesIgnoringSafeArea&lt;/code&gt; allows the overlay to ignore the safe area and go beyond the screen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then, we can add a simple Spring animation when the &lt;code&gt;selectedTab&lt;/code&gt; value changes to give a better overall experience:&lt;br&gt;
&lt;code&gt;.animation(.spring(), value: selectedTab)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;🎉 &lt;strong&gt;This is the final result:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj8m7awzdxtjt6l52za31.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj8m7awzdxtjt6l52za31.gif" alt="Light TabView"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It gets better on dark mode:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntr4sezex1yhaxkfazyp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntr4sezex1yhaxkfazyp.gif" alt="Dark TabView"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing to have in mind is that the overlay is on top of our &lt;code&gt;TabView&lt;/code&gt;, as the name says, so we have to be careful not to cover our tab items if we add something more than a &lt;code&gt;light&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That is it, simple and effective. I hope you enjoy the simplicity of SwiftUI like I do. 🚀&lt;/p&gt;

</description>
      <category>swiftui</category>
      <category>swift</category>
      <category>ios</category>
      <category>iosdev</category>
    </item>
    <item>
      <title>Cleaning your Xcode's garbage</title>
      <dc:creator>German</dc:creator>
      <pubDate>Tue, 14 Mar 2023 22:22:29 +0000</pubDate>
      <link>https://dev.to/germanxp/cleaning-your-xcodes-garbage-2g6g</link>
      <guid>https://dev.to/germanxp/cleaning-your-xcodes-garbage-2g6g</guid>
      <description>&lt;p&gt;Mobile devs out there with 128 or 256Gb SSDs Macbook: Hear me out!&lt;br&gt;
If you find yourself struggling with the available free space on your disk, like Xcode not building or Terminal commands failing. All these happen because they can't write files to the SSD.&lt;br&gt;
The good news are, I have a great solution for you:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/niklasberglund/xcode-clean.sh"&gt;Xcode-clean script&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Shout out to Niklas Berglund&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I found this script many years ago and I still use it, even when I am currently working on a 512Gb Macbook Pro.&lt;/p&gt;

&lt;p&gt;Of course there are several less technical alternatives to do this, like cleaner apps, cache cleaning tools, etc. &lt;br&gt;
But for some reason I tend to go with the nerdiest solutions.&lt;/p&gt;

&lt;p&gt;For convenience you can create an alias like I did. Add the following line to your bash profile, oh-my-zsh, or whatever shell you use:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alias cleanxcode='~/xcode-clean.sh/./xcode-clean.sh'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, you can use it like:&lt;br&gt;
&lt;code&gt;&amp;gt; cleanxcode --help&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usage: /Users/.../xcode-clean.sh/./xcode-clean.sh [options]

Frees up disk space by removing Xcode data. NOTE: you might want to keep backups of the dSYM files in ~/Library/Developer/Xcode/Archives

EXAMPLE:
    /Users/.../xcode-clean.sh/./xcode-clean.sh -A

OPTIONS:
   -h           Show this help message
   -b [path]    Backup dSYM files to specified path before removing archives
   -a           Removed all Xcode archives
   -d           Remove everything in DerivedData folder
   -D           Remove everything in DeviceSupport folder
   -s           Remove simulator data
   -A           Remove all of the above(archived, DerivedData and simulator data)
   --dry-run    Dry run mode prints which directories would be cleared but don't remove any files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A common use case for me is:&lt;br&gt;
&lt;code&gt;&amp;gt; cleanxcode -a -d -s&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It wiped out a total of 9Gb this time 👍🏻&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clearing archives in /Users/.../Library/Developer/Xcode/Archives/* (freeing 25M disk space)
Clearing DerivedData content in /Users/.../Library/Developer/Xcode/DerivedData/* (freeing 7.6G disk space)
Clearing simulator data in /Users/.../Library/Developer/CoreSimulator/Devices/* (freeing 1.4G disk space)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all for today.&lt;br&gt;
I hope you find it as useful as I do.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>xcode</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>How to Create a Live Streaming App</title>
      <dc:creator>German</dc:creator>
      <pubDate>Tue, 14 Mar 2023 11:57:00 +0000</pubDate>
      <link>https://dev.to/germanxp/how-to-create-a-live-streaming-platform-3e3o</link>
      <guid>https://dev.to/germanxp/how-to-create-a-live-streaming-platform-3e3o</guid>
      <description>&lt;h2&gt;
  
  
  How to Create a Live Streaming App
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Abstract:&lt;/strong&gt; A few ideas and considerations for architecting a live streaming application based on our previous experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Live streaming
&lt;/h3&gt;

&lt;p&gt;The term implies that the media(audio, video, or both) is broadcasted to the end-users in real-time. This is different than just &lt;em&gt;streaming&lt;/em&gt; which could refer to previously recorded content such as VOD(Video On Demand), music streaming, etc. Streaming media is delivered and played on demand rather than being generated simultaneously.&lt;/p&gt;

&lt;p&gt;This specific difference makes &lt;strong&gt;live streaming&lt;/strong&gt; a lot harder to design, implement and scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Live Streaming App
&lt;/h2&gt;

&lt;p&gt;There are different approaches you can take to build your live streaming platform:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implement your own.&lt;/li&gt;
&lt;li&gt;Use one of the existing &lt;strong&gt;Platform as a Service (PaaS)&lt;/strong&gt; solutions.&lt;/li&gt;
&lt;li&gt;Use an existing software solution that you can run on your own &lt;strong&gt;Infrastructure as a Service (IaaS)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While the first option sounds complicated (it is), it might be the best choice if you have the time, resources, and super specific requirements for your live streaming app. Since I wouldn't recommend coding the entire streaming software from scratch; a good starting point would be the open source solutions.&lt;/p&gt;

&lt;p&gt;Now, let's take a look at the pros and cons of options 2 and 3.&lt;br&gt;
These are proven to be a great launch pad for startups and also more complex solutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  PaaS
&lt;/h3&gt;

&lt;p&gt;There are a few PaaS around that allow you to quickly build your streaming app and take some sort of control on specific aspects of the streaming process, the audience, etc.&lt;br&gt;
The most popular are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.wowza.com/products/streaming-cloud"&gt;Wowza Streaming Cloud&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://antmedia.io/"&gt;AntMedia&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.brightcove.com/"&gt;Brightcove&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://azure.microsoft.com/en-us/services/media-services/#overview"&gt;Azure Media Services&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pros: these platforms will take care of all the scalability, configuration, and infrastructure.&lt;/p&gt;

&lt;p&gt;Cons: if your solution requires the live transmissions to start right away; these solutions won't work for you most of the time. The warm-up times are usually up to several minutes.&lt;/p&gt;

&lt;p&gt;A simple architecture preview using one of the PaaS above would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pCuuqbPx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1p22nlv0b66j8blwqi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pCuuqbPx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1p22nlv0b66j8blwqi0.png" alt="Architecture using PaaS" width="637" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These platforms are the best fit if you plan to broadcast scheduled live events. i.e: Sport events, concerts, TV Channels.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  SaaS
&lt;/h3&gt;

&lt;p&gt;The following media server software gives you all the capabilities required to live stream(ingest, transcode/transrate, output, etc).&lt;br&gt;
Pros: These are very flexible and allow you to tweak almost every parameter of the streamflow, add custom behaviors, and integrate with third-party tools.&lt;/p&gt;

&lt;p&gt;Cons: Contrary to the platforms, they don't provide any infrastructure and you will be in charge of the installation, configuration, and design along with putting all of this together in your cloud service. You are responsible for whether or not the solution scales. &lt;/p&gt;

&lt;p&gt;Some of them provide software-based load balancers and other mechanisms that help you to ease all the work previously mentioned.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.wowza.com/products/streaming-engine"&gt;Wowza Streaming Engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ant-media/Ant-Media-Server/wiki"&gt;AntMedia Server - Enterprise Edition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.red5pro.com/red5-media-server/"&gt;Red5 Media Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flussonic.com/flussonic-media-server/"&gt;Flussonic Media Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without much details on scaling and other mechanisms, a live streaming platform architecture using a SaaS could look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vHuCXo5l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19dhrbxpsfhumxs4qkzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vHuCXo5l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19dhrbxpsfhumxs4qkzn.png" alt="Architecture using SaaS" width="638" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This approach requires more work and resources to get your final solution working properly, but the possibilities are endless.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Considerations
&lt;/h3&gt;

&lt;p&gt;There are some questions that we must ask ourselves before thinking about a solution or anything else.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How critical is it to achieve the lowest latency possible?&lt;/li&gt;
&lt;li&gt;Where will the end-users be watching live streams?&lt;/li&gt;
&lt;li&gt;Should my platform support thousands or even millions of users?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answers to these questions will set a starting point for your investigations, POCs and even technologies and tools to use.&lt;/p&gt;

&lt;h4&gt;
  
  
  Latency matters
&lt;/h4&gt;

&lt;p&gt;This is one of the most important topics to analyze when architecting your solution, and you have basically two different scenarios.&lt;br&gt;
Let's say your platform will be streaming TV shows on a schedule, where viewers aren't allowed to comment or anything.&lt;br&gt;
In this particular scenario achieving low latencies is not necessary, and embracing a 15-30 seconds delay would be my recommended way to go.&lt;br&gt;
HTTP Live Streaming (HLS), Dynamic Adaptive Streaming over HTTP (DASH or MPEG-DASH), and Microsoft Smooth Streaming are some of the technology standards designed to stream media content to clients. They all work over  HTTP and in a very similar way, the media consists of a playlist of small chunks of data. The duration of the chunks, the number of chunks in each segment, amongst other things defines the theoretical delay mentioned above, making these standards worth considering for the current scenario.&lt;/p&gt;

&lt;p&gt;Then we have the second scenario, where your platform will need support for user engagement and interaction during the live streaming, and the real-time factor is critical. The most common real-time features we see in today’s apps are chats, polls, reactions, and screen sharing/collaboration.&lt;br&gt;
This requirement makes things more complex, specifically if we talk about scalability and synchronization.&lt;/p&gt;

&lt;p&gt;Real Time Messaging Protocol (RTMP), Real Time Streaming Protocol (RTSP) and Web Real-Time Communication (WebRTC) are the best options out there when ultra low latency is in play.&lt;br&gt;
They all support really low latencies, but the clear winner is WebRTC with its sub-second delay capabilities, closely followed by RSTP with just above 1 second delay. This is because WebRTC is based on UDP rather than TCP like RTMP does.&lt;br&gt;
Of course there are more differences and technical factors to consider. &lt;a href="https://blog.streamaxia.com/rtmp-versus-webrtc-which-one-to-choose-2020-report-fed7e4d84b18"&gt;Here&lt;/a&gt; is a short reading on those.&lt;/p&gt;

&lt;h4&gt;
  
  
  Live streaming Playback Feature
&lt;/h4&gt;

&lt;p&gt;Live streaming apps often allow users to watch the content from their mobile devices, computers, laptops and smart TVs.&lt;br&gt;
To support all these your streaming servers could transcode the original media into various streams to provide multiple playback formats.&lt;br&gt;
You should consider that not all platforms support all playback formats, or at least not natively and that some of them are more problematic with certain formats.&lt;/p&gt;

&lt;p&gt;Here are some of the facilities and obstacles you might face:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. Mobile
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;HLS playback is natively supported in both, iOS and Android.&lt;/li&gt;
&lt;li&gt;MPEG-DASH is not supported and a third party player is needed.&lt;/li&gt;
&lt;li&gt;RTMP is not supported and since it is Flash-based you will need to find a third-party player to use in your native app.&lt;/li&gt;
&lt;li&gt;RTSP playback is supported in Android but not in iOS.&lt;/li&gt;
&lt;li&gt;WebRTC is kind of in the same place that RTMP. It is designed for the web therefore you will also need a third-party library. This technology is gaining popularity rapidly so it will not be hard to find projects to bring support to the other platforms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For React Native apps, you can find ports for the most common libraries in iOS and Android. Have in mind that they usually don't offer the same flexibility or expose all the features from the original ones.&lt;/p&gt;

&lt;h5&gt;
  
  
  2. Web browsers
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Apple HLS is supported by Safari(as you should expect) in its iOS and MacOS versions.&lt;/li&gt;
&lt;li&gt;RTMP lacks support in this area as well. With Flash out of the picture, it is not a common choice for today's browsers.
Of course, you are not alone in this world, there are a few decent JavaScript implementations that you can use to play RTMP in your web.&lt;/li&gt;
&lt;li&gt;MPEG-DASH and RTSP are not supported out of the box in any browser. You still can find open source or propietary libraries though.&lt;/li&gt;
&lt;li&gt;Being WebRTC the most modern one, it is supported by pretty much every browser out there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;HLS and WebRTC are the options to have in mind when it comes to the playback with broad compatibility. It basically boils down to your latency needs.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Scalability
&lt;/h4&gt;

&lt;p&gt;Making your platform/app able to support more concurrent users than the estimate is key. This is one of the success metrics for your live streaming app and means that your end-users will not suffer from huge delays, video stuttering, and connection drops when the numbers get high.&lt;/p&gt;

&lt;p&gt;Here is when the delivery formats play an important role. If we will be streaming to our end users via HLS(or any of the HTTP based protocols) we are one step closer to the goal. The fact that the media chunks are sent over HTTP makes these protocols way easier to scale. The solution recommended is to put a well-known Content Delivery Network (CDN) to do all the work for us.&lt;/p&gt;

&lt;p&gt;The high availability servers of the CDN will allow the delivery of our streaming to scale indefinitely.&lt;/p&gt;

&lt;p&gt;By doing this we are surpassing a couple of challenges at the same time. A CDN will reduce the number of connections to our live streaming servers, allowing us to make better use of those and get the costs down. Since CDNs have servers all around the globe, it will also reduce the latency for already cached chunks when requested from regions too far from the origin servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most common cloud providers and their CDNs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/cloudfront/"&gt;AWS CloudFront&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.akamai.com/us/en/products/media-delivery/"&gt;Akamai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://azure.microsoft.com/en-us/services/cdn/#features"&gt;Azure CDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; &lt;a href="https://www.wowza.com/products/cdn"&gt;Wowza CDN&lt;/a&gt; matches perfectly with the Wowza Streaming Engine software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sG0OtGa9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j19ngnaiid3qef4p17sc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sG0OtGa9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j19ngnaiid3qef4p17sc.png" alt="Architecture using CDN" width="638" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delivering the content over HTTP is probably the best option for making your platform easily scalable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, what happens to the end users if you choose to stream via RTMP, RTSP, or WebRTC?&lt;br&gt;
Unfortunately, traditional CDNs aren't prepared for these protocols. We need to design our own server infrastructure to handle the load and scale properly, but don't worry; this is not a new problem.&lt;/p&gt;

&lt;p&gt;A broadly used concept is the &lt;strong&gt;origin-edge&lt;/strong&gt; configuration for the core of the architecture. This defines a clear separation of responsibilities between the live streaming servers. A &lt;strong&gt;origin&lt;/strong&gt; server would be the one in charge of ingesting the stream, and in some cases, also transcoding it to the delivery formats. On the other hand, &lt;strong&gt;edge&lt;/strong&gt; servers will fetch the stream from the origin (or a designated transcoder) and distribute it to the end users.&lt;/p&gt;

&lt;p&gt;This allows us to use our computing resources more efficiently. In the case of 1:many streaming applications, it allows for the distribution of connections between the edge servers, instead of overburdening the origin.&lt;/p&gt;

&lt;p&gt;With this in mind, a common practice is to horizontally scale the core of the platform architecture. This means we will be adding more &lt;strong&gt;origin-edge&lt;/strong&gt; groups as the application needs them. For the orchestration, a load balancer and an auto-scaling group can be placed around all the streaming groups.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o7l4t7vJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uz83g5wryq3p0epvpvdt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o7l4t7vJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uz83g5wryq3p0epvpvdt.png" alt="Custom streaming Architecture" width="627" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bear in mind this is not the only way to scale a live streaming application when using the previously mentioned protocols.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A key take away is knowing that scaling ultra low latency live streaming applications is way more expensive than using HTTP-Based protocols.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We hope you were able to learn more about building live-streaming apps.  In the next post of this series, we will provide more technical insights. Stay tuned to see how we solve challenges on a real Live Streaming app, test scalability, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source
&lt;/h2&gt;

&lt;p&gt;If you decide to build your own platform, want to build a quick POC, or maybe are just curious about the technologies; there are a few Open Source projects that are worth looking at.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/red5pro"&gt;Red5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/webrtc"&gt;WebRTC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ant-media/Ant-Media-Server"&gt;AntMedia Server - Community Edition&lt;/a&gt;(based on Red5)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;
  &lt;sup&gt;&lt;br&gt;
    Icons by:&lt;br&gt;
    &lt;a href="http://www.freepik.com/" title="Freepik"&gt;Freepik&lt;/a&gt; at &lt;a href="https://www.flaticon.es/" title="Flaticon"&gt; &lt;/a&gt;&lt;a href="http://www.flaticon.es"&gt;www.flaticon.es&lt;/a&gt;&lt;br&gt;
  &lt;/sup&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>livestreaming</category>
      <category>architecture</category>
      <category>cdn</category>
      <category>scalability</category>
    </item>
    <item>
      <title>What's great about our iOS base repository</title>
      <dc:creator>German</dc:creator>
      <pubDate>Tue, 14 Mar 2023 11:26:27 +0000</pubDate>
      <link>https://dev.to/germanxp/whats-great-about-our-ios-base-repository-4l3i</link>
      <guid>https://dev.to/germanxp/whats-great-about-our-ios-base-repository-4l3i</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kk8uRy66--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmsaq5yeheo8yt1p6wpg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kk8uRy66--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rmsaq5yeheo8yt1p6wpg.jpeg" alt="Increased productivity chart" width="626" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstract:&lt;/strong&gt; A prebuilt boilerplate code base can save time and effort when you create new projects. This article explains why a custom-built iOS base like ours works even better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; When you build a platform from scratch, some of the initial work might be the same for every project. You can save time by using one of many open-source code bases, or you can make your own. This article talks about the advantages of creating your own custom base.&lt;/p&gt;

&lt;p&gt;At Rootstrap, we develop custom-made software for our clients. Like any other service, we always want to deliver the best quality product. Some of these products are native iOS applications. And that’s where our fantastic iOS design teams shines. In this article, I talk about our &lt;a href="https://github.com/rootstrap/ios-base"&gt;iOS-base repository&lt;/a&gt; and how it improved our team collaboration and rocket-launched development times and productivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: repetitive work
&lt;/h2&gt;

&lt;p&gt;A few years ago, we noticed that whenever we coded a new app, the work was extremely repetitive. Over and over, we created the same base project structure, copy-pasted code from previous projects, and even reimplemented entire features. But thankfully, we identified that problem quickly. In a short time, we implemented our own version of a boilerplate project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first solution
&lt;/h2&gt;

&lt;p&gt;Our idea was simple, we wanted an XCode project that allowed us to jump right into feature development, perhaps with slight modifications or architecture changes. First, we put together everything that we needed in every new app. Those elements included a networking layer, a few handy dependencies, view customization helpers, and some useful Swift extensions. We even added example features for users to sign up and sign in to the app with local session storage.&lt;br&gt;
That project was it. It wasn’t very ambitious, but it saved a lot of setup time. And now, we had something to collaborate on and improve over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  No attachments
&lt;/h3&gt;

&lt;p&gt;The Rootstrap iOS project includes basic modules like session storage, routing, and analytics. It also comes with MVVM architecture, but nothing forces developers to use that pattern or any other aspect of the main project.&lt;br&gt;
As an engineer, you need to choose the right architecture for your application. Our iOS-base gives you a hassle-free way to do that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code quality
&lt;/h3&gt;

&lt;p&gt;One implicit goal was to centralize code quality standards for all iOS developers. At the same time, we wanted the project to contribute directly to our company goals.&lt;/p&gt;

&lt;p&gt;As a team, we reached an agreement on the requirements for good code quality and best practices. We made those standards the pillar of our code base. From there, we decided to take these actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adopt these &lt;a href="https://rootstrap.github.io/swift/"&gt;Swift style guides&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Configure &lt;a href="https://github.com/realm/SwiftLint"&gt;SwiftLint&lt;/a&gt; to run locally and in the continuous integration (CI) platform of preference. SwiftLint rules respond to our agreement and the style guide.&lt;/li&gt;
&lt;li&gt;Integrate &lt;a href="https://codeclimate.com/"&gt;Code Climate&lt;/a&gt; to ensure best coding practices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Things changed ... for the better
&lt;/h2&gt;

&lt;p&gt;If someone claimed that just by starting a new project from a boilerplate, their productivity improved by a magical percentage, I’d be skeptical. But the truth is that our boilerplate didn’t just improve productivity. It also improved many other aspects of our engineering team’s work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initial iterations were done faster, which grew client confidence.&lt;/li&gt;
&lt;li&gt;Adding the iOS base to our company’s shared knowledge base helped us develop similar features in record time.&lt;/li&gt;
&lt;li&gt;As an open source project, it generated interest in our iOS team members and increased their willingness to collaborate.&lt;/li&gt;
&lt;li&gt;The project increased company’s visibility in the tech community.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;You might ask “Why create another iOS boilerplate project when there are thousands of open source projects that do the same thing?” Some projects have more functionalities, and some are more specific. Despite their endless variations, you’ll never find one that solves all your specific and unique problems. Sure, you can fork the best match and adapt it to your needs. But you’ll miss a great opportunity to make the solution your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key points for building your own base
&lt;/h2&gt;

&lt;p&gt;These are some recommendations based on our experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open source it&lt;/strong&gt;
: You can get and give help to or from other contributors.
: The projects you open source showcase examples of your work and how things are done in your company.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pet it&lt;/strong&gt;.
: Continuous improvements, updates, and maintenance are important. For example, it doesn’t look good if you last committed to your project two years ago or it’s got build errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Professionalize maintenance&lt;/strong&gt;
: Create a GitHub/Jira project, a Trello board, or something similar for your repository. Professional maintenance organizes your managed milestones, new feature implementation, issues, and other project elements. Collaborative team projects, task assignments, and bench management also benefit when everything is maintained in one place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep it lean&lt;/strong&gt;.
: Every project has different needs. Avoid adding features that tie you to a specific implementation or service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, build something that respond to your needs, then generalize it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn more
&lt;/h2&gt;

&lt;p&gt;If you’re interested in the technical details of this project, check out the README at &lt;a href="https://github.com/rootstrap/ios-base"&gt;iOS-base repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>git</category>
      <category>collaboration</category>
      <category>swift</category>
    </item>
    <item>
      <title>How to Train Senior iOS Engineers</title>
      <dc:creator>German</dc:creator>
      <pubDate>Tue, 14 Mar 2023 11:07:01 +0000</pubDate>
      <link>https://dev.to/germanxp/how-to-train-senior-ios-engineers-1n4</link>
      <guid>https://dev.to/germanxp/how-to-train-senior-ios-engineers-1n4</guid>
      <description>&lt;p&gt;At this point, you’ve most likely heard of the employee training dilemma. If not, it goes like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manager A:&lt;/strong&gt; What if we train them and they leave?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manager B:&lt;/strong&gt; What if we don’t, and they stay?!&lt;/p&gt;

&lt;p&gt;In other words, should we train our employees knowing they could leave the company after we invested in them? Or should we train them because we want them to (and they could) stay in the company and bring much more value from that investment?&lt;/p&gt;

&lt;p&gt;Investing in employee training is critical to building a successful business, as it helps to ensure that employees have the skills and knowledge they need to perform their roles effectively. &lt;/p&gt;

&lt;p&gt;At Rootstrap, we take this seriously, with one of our yearly goals being to provide meaningful experiences and career growth opportunities for our team members. Furthermore, the company's vision is to become digital masters, and investing in our team is key to achieving this goal. &lt;/p&gt;

&lt;p&gt;In this article, we'll take a closer look at the training plan we've developed for our iOS team at Rootstrap and how it aligns with our company vision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rootstrap iOS Training Plan
&lt;/h2&gt;

&lt;p&gt;Our goal was to have a training plan to put people on the right track to becoming &lt;strong&gt;senior iOS developers&lt;/strong&gt;. Of course, completing a list of classes and reading a bunch of books doesn’t automatically make you senior, but the purpose is to set the foundations and define a clear path that a developer should follow in no particular order.&lt;/p&gt;

&lt;p&gt;In a coordinated effort with other managers and experienced technical roles, the process began by determining the main learning modules representing the branches of a hypothetical tree. Also, we wanted to be aligned with the expected outcomes for each one of these key topics. Let's call them ‘the fruits.’&lt;br&gt;
‍&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v4OYw-z6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nqyr1ptqajynex7374k.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v4OYw-z6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0nqyr1ptqajynex7374k.jpeg" alt="Learning tree" width="880" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an example, we defined the Programming module as the core of the Learning Path and set the expected outcomes as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developer knows what Object Oriented Programming is all about and good practices to make the code easier to understand and maintain.&lt;/li&gt;
&lt;li&gt;Developer has intermediate/advanced knowledge of the language and frameworks they use regularly.&lt;/li&gt;
&lt;li&gt;Developer knows how to properly write documentation for an API and use automatic tools that use code annotations.&lt;/li&gt;
&lt;li&gt;Developer knows what Code Smells are and remembers many of their names. While doing code reviews, they can identify them easily and make good suggestions.&lt;/li&gt;
&lt;li&gt;Developer knows the main classifications for Refactorings and remembers many concrete refactorings. They refactor their code frequently, and while doing code reviews, they make good suggestions.
Of course, each of these outcomes would have one or more actionable items that would make them achievable while going through the path. Here is the complete list of modules with a glance at their contents:&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Programming:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Swift &amp;amp; iOS development frameworks (UIKit, SwiftUI, Combine, etc.) proficiency.&lt;/li&gt;
&lt;li&gt;The fundamentals of API Programming and documentation.&lt;/li&gt;
&lt;li&gt;Good practices and common techniques for debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Understand concepts around testing.&lt;/li&gt;
&lt;li&gt;When and why to write different types of tests.&lt;/li&gt;
&lt;li&gt;Write meaningful and valuable tests for your iOS applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Accessibility:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Understand basic to advanced concepts around accessibility and its importance.&lt;/li&gt;
&lt;li&gt;How to test accessibility in your applications.&lt;/li&gt;
&lt;li&gt;Create accessible applications. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Monitoring and Performance:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Understand concepts around monitoring and debugging mobile applications.&lt;/li&gt;
&lt;li&gt;How to monitor applications using Xcode and third-party tools.&lt;/li&gt;
&lt;li&gt;Techniques and how to debug applications with Xcode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Apple App Distribution:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Understand concepts around certificates, App IDs, and provisioning profiles.&lt;/li&gt;
&lt;li&gt;Use the different dependency managers for Swift frameworks.&lt;/li&gt;
&lt;li&gt;Release apps for Beta Testing via TestFlight.&lt;/li&gt;
&lt;li&gt;Create reusable Swift Frameworks.&lt;/li&gt;
&lt;li&gt;Release apps to the AppStore.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Continuous Integration &amp;amp; Delivery:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Set up CI/CD workflows in GitHub Actions and Bitrise for your applications.&lt;/li&gt;
&lt;li&gt;Submit applications to AppStore Connect via your CI/CD platforms.&lt;/li&gt;
&lt;li&gt;Understand concepts around Fastlane tooling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also added supplementary modules for &lt;strong&gt;Git&lt;/strong&gt;, &lt;strong&gt;Estimations&lt;/strong&gt;, and &lt;strong&gt;Client Facing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;‍&lt;/p&gt;

&lt;h2&gt;
  
  
  The Nitty-gritty
&lt;/h2&gt;

&lt;p&gt;Now, the developers need to be able to grow each branch, so they can finally get to the fruits, and we provided a list of tasks so they can do so. They just need to invest time in the proposed assignments for each module.&lt;/p&gt;

&lt;p&gt;One of the requisites was having different materials for each topic. All of us learn differently; some prefer audiovisual content, while others prefer to read, for example. &lt;/p&gt;

&lt;p&gt;With that said, we aimed to have all the most common types (articles, books, and courses) for each topic so they could pick based on their interests without missing any critical pieces.&lt;/p&gt;

&lt;p&gt;‍&lt;br&gt;
The process of picking the best-value content was hard and time-consuming. There is a lot of documentation online for any topic you would imagine. We had to assess each one of the materials we added to the Learning Path for three important aspects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Match our knowledge expectations i.e. great content.&lt;/li&gt;
&lt;li&gt;Be up-to-date and recent.&lt;/li&gt;
&lt;li&gt;Conform to our average time-value expectation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally, each module needed a section to put all that knowledge into practice, so we added exercises. This one was also tricky, and it took a lot of work to find practical exercises to match the needs of every single module.&lt;/p&gt;

&lt;p&gt;We ended up going with a hybrid approach, using external sources and in-house practice tools. For example, a custom Xcode project was designed to evaluate the Monitoring and Performance module, while some open-source Katas were good enough for some aspects of the Programming module.&lt;/p&gt;

&lt;h2&gt;
  
  
  Centralizing The Training Plan
&lt;/h2&gt;

&lt;p&gt;It was time to publish all the work and make it available for the team, and this is where Northpass came in. Northpass is a great tool used in Rootstrap University to manage the team's training. Learn more about Rootstrap's Learning Camps.&lt;/p&gt;

&lt;p&gt;As touched on, the training plan can be completed in no particular order, and this is one of many capabilities of the Learning Paths with this tool.&lt;/p&gt;

&lt;p&gt;We defined the modules as independent courses in Northpass that could even be accessed outside of the path itself, while in conjunction, they give shape to our Advanced iOS Engineer Learning Path.&lt;/p&gt;

&lt;p&gt;‍&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens Next?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Feedback
&lt;/h3&gt;

&lt;p&gt;We released the training plan, including a section to receive feedback from developers who enrolled quickly. We have already collected some positive feedback, but it is still early to make decisions based on that. The goal is to allow people to rate the quality and quantity of the content in each module they complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Detecting opportunities
&lt;/h3&gt;

&lt;p&gt;You might wonder how we are using the training plan or how people in the team know what they need to complete. It is the responsibility of both leaders and individuals to identify which skills or learning areas to prioritize. Leaders will work closely with each developer to help them achieve their career goals.&lt;/p&gt;

&lt;p&gt;Some areas can be used to detect goal-setting opportunities: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code review&lt;/li&gt;
&lt;li&gt;Devs interests&lt;/li&gt;
&lt;li&gt;Company interests&lt;/li&gt;
&lt;li&gt;Specific needs from sales leads or clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand, the team members can enroll in the Learning Path or any independent courses via our Learning Hub based on their individual goals.&lt;br&gt;
‍&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future
&lt;/h2&gt;

&lt;p&gt;Managers and higher-level technical roles will push the evolution of the training plan by encouraging others to take ownership of the talent growth in the company and make it an organization-wide effort at the end of the day.&lt;/p&gt;

&lt;p&gt;We now have a long way ahead, and this is a continuous work that will need to be adapted and improved to respond to various factors. The team and company need change, and the documentation gets outdated, new technologies emerge, and so on. More to come on this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Growth
&lt;/h2&gt;

&lt;p&gt;We've developed a comprehensive training plan for our iOS team to help members develop the skills and knowledge needed to become senior developers. By providing a clear path for growth and development, along with actionable tasks and activities, our team members will be well-equipped to achieve their goals and make meaningful contributions to our company's vision of becoming digital masters. &lt;/p&gt;

&lt;p&gt;Overall, the training plan is a great way to retain talent, improve the team's skills and achieve better outcomes for the company. Feel free to leave any thoughts and questions in the comments section. We are happy to provide more information and take recommendations on board to help us improve.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://www.rootstrap.com/blog/how-to-train-senior-ios-engineers"&gt;Original post here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>training</category>
      <category>engineers</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
