<?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: Noemi Rozpara</title>
    <description>The latest articles on DEV Community by Noemi Rozpara (@noemi_rozpara).</description>
    <link>https://dev.to/noemi_rozpara</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%2F227075%2F509509b8-58da-4a68-a9e2-7b501d8aecfc.png</url>
      <title>DEV Community: Noemi Rozpara</title>
      <link>https://dev.to/noemi_rozpara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/noemi_rozpara"/>
    <language>en</language>
    <item>
      <title>A Success Story: I Didn’t Get the Job</title>
      <dc:creator>Noemi Rozpara</dc:creator>
      <pubDate>Mon, 06 May 2024 11:03:47 +0000</pubDate>
      <link>https://dev.to/noemi_rozpara/a-success-story-i-didnt-get-the-job-amb</link>
      <guid>https://dev.to/noemi_rozpara/a-success-story-i-didnt-get-the-job-amb</guid>
      <description>&lt;h3&gt;
  
  
  TLDR; 
&lt;/h3&gt;

&lt;p&gt;My recent experience of the horrid recruitment process didn’t end up in collaboration, and I’m truly happy about it! The experience taught valuable lessons about communication, setting boundaries, and recognizing red flags in the hiring process.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Started 
&lt;/h3&gt;

&lt;p&gt;As some of you may know, recently I started looking for a new project. After a few months of my burnout break, I felt ready for a new gig. I posted this Tweet:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey folks, I’m back on the market! Do you know of any macOS/iOS projects I could help with? 😊 &lt;br&gt;
Must-have: great work culture 🤝 &lt;br&gt;
Great to have: part-time (20-32 hrs/week) &lt;br&gt;
Nice to have: multimedia domain, but I’m really open here 🎨&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hoped to boost my search a bit. While I kept browsing social media and work-related platforms, I was aware that I don’t see all possible projects. In case I missed my dream job, I hoped someone would see this Tweet and reach out to me. And it worked!&lt;/p&gt;

&lt;p&gt;A PM I know texted me that it was perfect timing. The startup he worked for was considering some additional iOS consulting. We arranged the call so he could share some more details. The role ticked all the boxes: part-time consulting in a multimedia-related project. He also claimed the culture of work was great, and knowing this person, I knew our views in this area were aligned. The company, despite its small size, had no pressure to grow fast. They rather cherished the chance to collaborate closely across the teams. Everyone had some contribution to the roadmap. And instead of setting up deadlines, they just published whatever was production-ready.&lt;/p&gt;

&lt;p&gt;The only problem was, the iOS team was noticeably slower than other platform teams. But there was a reasonable explanation for it. iOS was the first supported platform. Unfortunately, the person laying out the foundation of the app was as skilled as toxic. For a while, it was tolerated. But the real problem emerged with the need to expand the engineering team. A new engineer didn’t understand the overly complicated code and didn’t want to work with this person. So the technical founder was made redundant. The new engineer took over the app, and one more developer was hired to help him. After a while, the consequences of the bad start were still there, as the legacy code was slow to develop, especially considering the non-trivial domain.&lt;/p&gt;

&lt;p&gt;I got really excited about this opportunity. I had some experience with multimedia. As a person who worked mostly on small projects, I wasn’t afraid to get my hands dirty. And the part-time role would give me a lot of space for my loved ones and hobbies. We agreed I was going to meet the principal engineer. He was going to outline the current shape of the app and the challenges I could help with.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Promising Meeting 
&lt;/h3&gt;

&lt;p&gt;We met a few days later. The engineer — let’s call him Adam — created a good first impression, of being both experienced and communicative. We were happy to find out I could help them indeed. In the past, I have already solved challenges similar to the ones the app was facing. But what mattered to me the most, we were able to discuss these issues in a substantive way. We brainstormed possible solutions, considering both the bright and the downsides of each one. The whole conversation was educational and uplifting.&lt;/p&gt;

&lt;p&gt;We agreed on arranging one last call, so I have a chance to meet his collaborator and talk a bit more about the technical details. I wanted to prepare myself, so I specifically asked if the following call will be the classical technical interview. Adam told me to expect just a chat. That was relieving to hear, so I didn’t stress much about the meeting. The only preparation I did was double-checking the docs. Adam mentioned one API they were using. I had a hunch that abusing it might be one of their performance bottlenecks. My suspicion was confirmed by the first paragraph of the docs. I made a note, hoping to share this insight next time we chat.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Worst Meeting in My Career
&lt;/h3&gt;

&lt;p&gt; When joining the meeting scheduled two days later, I was relaxed and self-confident. I was also excited about meeting my — presumably — future coworker. The other developer — let’s call him Bob — welcomed me in a rather grumpy way. But I ignored it; maybe he just wasn’t in shape. We started with small talk, which was interrupted by Bob in not exactly a smooth way: “Ok, that was the small talk, we can start the questions list”. I got puzzled and asked what list. “A list of the interview questions”. I reminded Adam that I specifically asked about this, and he claimed this meeting wasn’t going to be an interview. He asked me if that was really the case, and if so, it must have been a miscommunication.&lt;/p&gt;

&lt;p&gt;I’m allergic to the word “miscommunication”. In most cases, it’s an attempt to say “you got it wrong, get over it, it will be my way”. My question wasn’t too ambiguous. I wasn’t prepared for any generic theoretical questions, especially considering my six months' break from any coding. They apologized and explained that the last time they hired someone without an interview, it turned out this person was hardly capable of coding. This time they wanted to do &lt;em&gt;something&lt;/em&gt;, so they Googled some list of questions. And if I didn’t mind, they wanted to give it a shot.&lt;/p&gt;

&lt;p&gt;I deeply regret I agreed to proceed. I got a bunch of academic questions, like “what’s the paradigm in Swift”. Sure, every day at work I use protocols. I also have a comparison with other coding languages. Whenever I do something, I make sure to have at least a brief understanding. But since I expected something completely different from this meeting, I missed even the vocabulary. I felt like someone would wake me up in the middle of the night and examine me. I tried to keep it cool, so I decided I was going to reshape this formula a bit more into the conversation. No luck. It didn’t matter if I said an anecdote about this topic from my practical experience or asked them about their experiences instead. Every time after reaching a few sentences, Bob interrupted me: “Ok, cool, on to the next question”.&lt;/p&gt;

&lt;p&gt;This awkward questioning lasted almost one hour, which was the preserved time slot. Adam thanked me for that part and said we can move on to the more practical part of the meeting: the chat about the multimedia-related issues. I drew the line here (brain, why not earlier?). I said we’re not moving anywhere. Since the beginning of the meeting, I kept answering the questions I didn’t expect, failed miserably chatting with them, and sounded stupid. At that point, I was emotionally drained. I gave them a choice: we could make a break, or schedule another meeting. It took us another half an hour to decide and schedule another meeting.&lt;/p&gt;

&lt;p&gt;At the end, I asked them two simple questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Were they any closer to decide if they want to collaborate with me?&lt;/li&gt;
&lt;li&gt;Did the questions helped them to know if I have the skills needed to solve their current issues?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I expected, both answers were negative.&lt;/p&gt;

&lt;p&gt;The whole experience was dreadful to me. Until the end of the day, I had flashbacks from this meeting. I decided to text the PM who reached out to me originally. I briefly described the meeting and he got shocked. He said he knew Bob was a bit introverted, but he had a good opinion about both developers. PM apologized to me, thanked me for my feedback, and said he was going to chat to the Head of Engineering about it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Final Meeting
&lt;/h3&gt;

&lt;p&gt; I didn’t hear from anyone until the time of the next scheduled meeting. I hesitated if I should join it or not. I decided to give it a go, hoping it was a one-time mistake, and the project would turn out great. Upon joining, I was surprised by more attendees than what I expected from the invitation. Apparently, the HoE decided to join and lead this meeting. I kept my poker face waiting how this meeting develops. And I was relieved to see the meeting was incomparably better than the previous one. HoE had much better interpersonal and business skills. He led the conversation in the manner which I expected from the previous meeting. He asked me about my experiences, e.g., the most gnarly bugs I managed to solve. He said my first task could be the videos upload and asked about my approach. I sketched how I would tackle this problem, with the issues I would expect on my way. We tried to keep the conversation on a high level, without too many technical details.&lt;/p&gt;

&lt;p&gt;Unfortunately, Bob’s vision was different. He kept asking me detailed questions about the specific APIs I would use. I kept repeating that I didn’t know; it would depend on their tech stack and available options. He insisted, so I explicitly said I didn’t think it was the best time to go into such detail. Luckily HoE supported me. We wrapped up this section of the meeting, and it was the time for the questions from the engineering team. Adam asked me about the best performance practices. I reminded myself of the note I took after the first meeting, so I mentioned creating objects once and keeping them around. Once more Bob tried to argue with me claiming it can’t be important. I just told him to read the docs. Geez!&lt;/p&gt;

&lt;p&gt;The only thing which kept me on this meeting was the fact I wouldn’t work with these developers on a regular basis. My role would be to spot the issues and fix them independently. Nonetheless, I wanted to establish some opinion about these people, so I had a chance to collaborate with them in the best possible way. We once more reached the end of the time slot for the meeting. But I asked for extra time, so I had the chance to ask them a few questions. To get a grasp of the workflow, I asked them about their casual day at work, who assigns issues, or how do they review code. I didn’t expect any specific answers; I just wanted to get to know them.&lt;/p&gt;

&lt;p&gt;At the end, I asked my favorite question: “Did you have any strong disagreements? If so, how did you solve it?”. Bob said he has a good example and actually smiled for the first time (!). He said they couldn’t agree on how to style the UI components, so in &lt;em&gt;his&lt;/em&gt; classes he uses one modifier, and in &lt;em&gt;Adam’s&lt;/em&gt; classes, Adam uses another one. He seemed proud of what he has said. I hanged for a second, then thanked him for sharing. I added that personally, I would prefer to keep the consistent codebase. It was after the meeting when I realized how bad that answer was. Beginning with the idea that the class is Bob’s or Adam’s. It’s not; the class belongs to the project. And the programmers are the members of the team developing the project. There shouldn’t be that much room for the ego. It became clear to me why the code hasn’t been refactored for such a long time. I remembered that Adam was hired three years ago. That’s quite a long time for the cleanups in the app, which doesn’t have that many features! But this time must have been spent wisely, definitely not on the arguments over syntax.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Ended 
&lt;/h3&gt;

&lt;p&gt;I texted the PM one more time and shared my thoughts. He said the HoE made similar conclusions, and they were grateful for my questions. Until that day, the whole company was blind to the issues they were having. The iOS team did the doorkeeping, blaming some guy from the past for the slow development pace. They had no idea what to do about it though. The PM sent me a message: “As a friend, I’d say stay away”, and that he doesn’t want to put me in the crossfire.&lt;/p&gt;

&lt;p&gt;For a while, I was pretty bitter about this whole process. I had high hopes for this project. Then I got in the ambitious mood, thinking that maybe I can join them after all. I’d drive the process of cleaning up both code and the ways of working. But at the end of the day, I really appreciate the honesty of the PM. I’m sure that’s not the only opportunity around. And my energy is limited, so I’d rather spend it on more fun duties.&lt;/p&gt;

&lt;p&gt;Few Takeaways From the Whole Experience:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Communication is Key:&lt;/strong&gt; Clear and honest communication can prevent many problems. Also, sending a written confirmation allows everyone to refresh the memory. I wish I did it!&lt;br&gt;
&lt;strong&gt;2. Trust Your Instincts:&lt;/strong&gt; If something doesn't feel right during the interview process, probably will just get worse later. Be honest with yourself and don’t be afraid to abort the process. &lt;br&gt;
&lt;strong&gt;3. Value Your Time and Energy:&lt;/strong&gt; Your time and energy are limited. Focus on investing them in opportunities that are fulfilling and align with your values. Also, “No” is a valid answer!&lt;/p&gt;

&lt;p&gt;Since I can’t undo this energy investment, I appreciate it as an important lesson. Staying optimistic, looking forward to joining my dream team!&lt;/p&gt;

</description>
      <category>career</category>
      <category>workplace</category>
      <category>recruitment</category>
      <category>communication</category>
    </item>
    <item>
      <title>RxSwift - easy, yet not obvious, tips</title>
      <dc:creator>Noemi Rozpara</dc:creator>
      <pubDate>Thu, 21 Jan 2021 14:26:05 +0000</pubDate>
      <link>https://dev.to/noemi_rozpara/rxswift-easy-yet-not-obvious-tips-34o0</link>
      <guid>https://dev.to/noemi_rozpara/rxswift-easy-yet-not-obvious-tips-34o0</guid>
      <description>&lt;p&gt;Last few months were for me my personal RxSwift bootcamp. I decided to refactor my app and rewrite a few big protocols to observables. This helped me to view Rx with a fresh eye and catch a few problems. Those might not be obvious for people who do presentations or boot camps or are familiar with this technology for a long time. Some - or all - of the points might be silly for you. But if I will save just one person from being confused, it was worth it! So without a further ado, let’s jump to the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rx is just an array + time
&lt;/h2&gt;

&lt;p&gt;I think this is the most important thing to understand with all your heart. All &lt;code&gt;subjects&lt;/code&gt;, &lt;code&gt;relays&lt;/code&gt; and operators might seem scary, especially with Rx-hermetic jargon.  But simplifying it in your head to a simple collection will help you to understand all concepts easily. For me it was a sudden click. If you want to learn more, official docs are great source and emphasize this concept: &lt;a href="https://github.com/ReactiveX/RxSwift/blob/main/Documentation/GettingStarted.md#observables-aka-sequences" rel="noopener noreferrer"&gt;https://github.com/ReactiveX/RxSwift/blob/main/Documentation/GettingStarted.md#observables-aka-sequences&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Oh, those memories
&lt;/h2&gt;

&lt;p&gt;RxSwift syntax is elegant. But sometimes it makes it harder to spot the moment, when you create strong reference cycles. Also, this issue is ignored by many learning resources. Authors are trying to maintain snippets as clean as possible. It took me a while to get to that by myself. &lt;/p&gt;

&lt;p&gt;Problem: we have a strong reference to &lt;code&gt;self&lt;/code&gt; inside a callback. And &lt;code&gt;self.disposeBag&lt;/code&gt; holds the strong reference to the callback. Finally it’s not getting cleaned up forever. &lt;/p&gt;

&lt;p&gt;How to solve it? Always include &lt;code&gt;[weak self]&lt;/code&gt; or &lt;code&gt;[unowned self]&lt;/code&gt; when you are passing a lambda to &lt;code&gt;subscribe&lt;/code&gt;, &lt;code&gt;drive&lt;/code&gt; or &lt;code&gt;bind&lt;/code&gt;, which includes any reference of &lt;code&gt;self&lt;/code&gt; inside. Be cautious for implicit self calls! You don’t need to do that, when you are binding rx property. &lt;/p&gt;

&lt;p&gt;Few examples: &lt;/p&gt;

&lt;p&gt;No need to do anything for driving or binding to rx attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;statusLabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UILabel&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

&lt;span class="n"&gt;myModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statusLabel&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;statusLabel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disposed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No need to do anything if callback doesn’t include &lt;code&gt;self&lt;/code&gt; or it’s weak reference already:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;myModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statusLabel&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;newLabel&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newLabel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disposed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;@IBOutlet&lt;/span&gt; &lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;statusLabel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UILabel&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

&lt;span class="n"&gt;myModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statusLabel&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;newLabel&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;statusLabel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newLabel&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disposed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;weak&lt;/code&gt; or &lt;code&gt;unowned self&lt;/code&gt; when callback includes self:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;myModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statusLabel&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;weak&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;newLabel&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;self&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;saveNewLabelSomewhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;newLabel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disposed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;saveNewLabelSomewhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: you might want to use simplified, pretty syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;myModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;statusLabel&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;saveNewLabelSomewhere&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disposed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;… but that would create the same problem. &lt;/p&gt;

&lt;h2&gt;
  
  
  Be careful with ViewController lifecycle
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What time for binding is the best?
&lt;/h3&gt;

&lt;p&gt;In most tutorials I have seen an example of doing all ViewController setup in &lt;code&gt;ViewDidLoad&lt;/code&gt;. It’s comfortable, you do it once, when ViewController is removed from the memory, it will clean up all resources, that’s it. But in reality I noticed 2 things: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Users tend to leave your app running in the background,&lt;/li&gt;
&lt;li&gt;Usually you don’t need to compute anything on screens, which are not visible at the moment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those observations led me to the conclusion that a much better option is to do all bindings in &lt;code&gt;ViewWillAppear&lt;/code&gt; and to clean the &lt;code&gt;disposeBag&lt;/code&gt; in &lt;code&gt;ViewWillDisappear&lt;/code&gt;. That way you only use resources for what’s needed on the screen, and you explicitly know when the subscription is finished. It helped me to follow the subscription flow in the controllers. &lt;/p&gt;

&lt;h3&gt;
  
  
  Subscriptions can be accidentally duplicated
&lt;/h3&gt;

&lt;p&gt;Sometimes you will need to subscribe more often than once for the screen - like in &lt;code&gt;viewDidLayoutSubviews&lt;/code&gt;. In such a case watch out to not to leave zombie subscriptions behind! Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;viewDidLayoutSubviews&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uiRelatedStuff&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disposed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happened is &lt;code&gt;viewDidLayoutSubviews&lt;/code&gt; probably was called a few times on screen load. Maybe another few times after the user rotated the screen. But the disposeBag is still alive! The effect is we have few copies of the same subscription. You can expect some bizarre side effects, like duplicated API calls.&lt;/p&gt;

&lt;p&gt;Long story short: make sure you subscribe once for every time you need to, it’s not obvious. &lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t reinvent the wheel
&lt;/h2&gt;

&lt;p&gt;RxSwift library provides us with many special types, or &lt;code&gt;traits&lt;/code&gt;. You need a warranty that call will happen from the main thread? You need to share effects? Before you write another few lines of code, check first if you could use a special type created for that purpose! I won’t be describing all of them here, check the docs: &lt;br&gt;
&lt;a href="https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Traits.md" rel="noopener noreferrer"&gt;https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Traits.md&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Subjects.md" rel="noopener noreferrer"&gt;https://github.com/ReactiveX/RxSwift/blob/main/Documentation/Subjects.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the other hand, don’t use &lt;code&gt;BehaviorSubject&lt;/code&gt; everywhere now - make sure a simpler type wouldn’t do. Sometimes less is more :)&lt;/p&gt;
&lt;h2&gt;
  
  
  Yes, you should test that, too
&lt;/h2&gt;

&lt;p&gt;I must admit: writing tests isn't my favorite part of the job. But I found out testing Rx is simpler than I thought! &lt;/p&gt;

&lt;p&gt;The easiest way to think of it for me is: you test the Rx element by observing like you would do normally. You just use fake the subscriber. And what you are actually testing is a collection of events emitted (value + time).&lt;/p&gt;

&lt;p&gt;The example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;XCTest&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;RxSwift&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;RxTest&lt;/span&gt;
&lt;span class="kd"&gt;@testable&lt;/span&gt; &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;MyFancyApp&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;PLPCoordinatorContentModelTests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;XCTestCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;scheduler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;TestScheduler&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;DisposeBag&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;scheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;TestScheduler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;initialClock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;disposeBag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;DisposeBag&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// simply reassigning new DisposeBag does the job &lt;/span&gt;
  &lt;span class="c1"&gt;// as the old one is cleaned up&lt;/span&gt;
  &lt;span class="n"&gt;disposeBag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;DisposeBag&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;testStatusLabelObservable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;MyViewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;// create observer of the expected events value type&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;testableLabelObserver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

  &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;titleObservable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newStatus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
  &lt;span class="c1"&gt;// just pass the value to the fake observer&lt;/span&gt;
    &lt;span class="n"&gt;testableTitleObserver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onNext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disposed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// schedule action which would normally trigger the observable &lt;/span&gt;
  &lt;span class="c1"&gt;// (see note below the snippet)&lt;/span&gt;
  &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scheduleAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;searchFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="kt"&gt;Kittens&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// more events if you need, then&lt;/span&gt;
  &lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;// define what you expect to happen&lt;/span&gt;
  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;expectedEvents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Recorded&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Inital Label Value"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Found Some Kittens!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="c1"&gt;// and check!&lt;/span&gt;
  &lt;span class="kt"&gt;XCTAssertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subscriber&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expectedEvents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note about scheduling events: you also can do this in bulk if you need more events than one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createColdObservable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="kt"&gt;Kittens&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="kt"&gt;Puppies&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disposed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disposeBag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;scheduler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;expectedEvents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Recorded&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Inital Label Value"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Found Some Kittens!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Search cleared"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Found Some Puppies!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;That’s it! You could describe flow above as: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create test scheduler which will handle events&lt;/li&gt;
&lt;li&gt;Create fake observable&lt;/li&gt;
&lt;li&gt;Subscribe fake observable to actual value you want to test&lt;/li&gt;
&lt;li&gt;Schedule some events&lt;/li&gt;
&lt;li&gt;Run scheduler&lt;/li&gt;
&lt;li&gt;Compare produced events to the expected ones &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Worth noting - scheduler works on virtual time, which means all operations will be executed right away. The values provided (like 10, 20 in examples above) are used to check the order and match to clock “ticks”.&lt;/p&gt;

&lt;p&gt;Brilliant resources about testing RxSwift are here: &lt;br&gt;
&lt;a href="https://www.raywenderlich.com/7408-testing-your-rxswift-code" rel="noopener noreferrer"&gt;https://www.raywenderlich.com/7408-testing-your-rxswift-code&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/16-testing-with-rxtest#toc-chapter-020" rel="noopener noreferrer"&gt;https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift/v4.0/chapters/16-testing-with-rxtest#toc-chapter-020&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rx all the things!
&lt;/h2&gt;

&lt;p&gt;… not. When you will feel comfortable with reactive concepts, you might feel an urge to refactor all the code to Rx. Of course, it’s nice and tidy. But it has few downsides: it’s hard to debug and you need to think about the time and memory. Also - equally important - not everyone is comfortable with that. So if your team is not ready, then it might be a good idea to hold on. &lt;/p&gt;

&lt;p&gt;When and where to use it then? There are no silver bullets. If you have a simple component, like a &lt;code&gt;TableView&lt;/code&gt; cell, then observables can be an overkill. But if you have a screen on which every time status changes you need to manually update 10 UI elements, then observing can be a charm. Also you can always apply RxSwift to one module of your app and decide upon further development. &lt;/p&gt;

&lt;p&gt;After all, doing those small decisions and maneuvering between endless technical solutions is the most difficult and beautiful part of a developer's job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I hope the list above is helpful to some of you. Let me know if I made any mistake! Also can you think of some other non-obvious RxSwift gotchas? Leave that in comment below :) &lt;/p&gt;

</description>
      <category>swift</category>
    </item>
    <item>
      <title>Effective business VS flu season</title>
      <dc:creator>Noemi Rozpara</dc:creator>
      <pubDate>Tue, 03 Mar 2020 12:38:18 +0000</pubDate>
      <link>https://dev.to/noemi_rozpara/effective-business-vs-flu-season-3hke</link>
      <guid>https://dev.to/noemi_rozpara/effective-business-vs-flu-season-3hke</guid>
      <description>&lt;p&gt;I decided to use the hassle surrounding the new virus to tackle a problem that has existed at least since I got my first job: how to resolve the conflict between business goals and health during flu season.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important note
&lt;/h3&gt;

&lt;p&gt;Remote work has its pros and cons. I graduated from an economics university, so I understand business needs. The content below considers both company objectives and developers' well-being.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we even talk about this?
&lt;/h3&gt;

&lt;p&gt;The topic might sound trivial or obvious. Yet, I believe everyone has been in a situation where they woke up feeling unwell but decided to go to work anyway. The excuses can be quite creative: "I have an important meeting today," "What if I need my sick leave days more in the future?" or "I didn’t perform my best last week; my boss will be angry." This list can go on indefinitely.&lt;/p&gt;

&lt;p&gt;This type of thinking is familiar to me, but I believe it is a shortsighted approach. When you feel unwell right after getting out of bed, your coworkers will likely suggest going home after a few hours. Perhaps a better solution is to stay in bed. If you're well enough, take some vitamins and a blanket and try to work remotely. However, it may also be the case that you cannot do even that. In such a situation, be honest with your team and your customers. Putting immense pressure on yourself when you're really unable to deliver results won’t help your health or the project. Sometimes, it's better to ask someone else to step in, especially if something needs urgent attention. Also, don’t worry about all the possible sick leave days you might need in the future. Face the truth: with this approach, you're likely to use none until the end of the year.&lt;/p&gt;

&lt;p&gt;Another crucial point is that &lt;strong&gt;health is everyone's responsibility&lt;/strong&gt;. If you have a business meeting with a customer, will sneezing constantly help you maintain a good impression of your company? If someone catches the flu a few days later, you could be the one to blame. The same goes for your coworkers.&lt;/p&gt;

&lt;h3&gt;
  
  
  But I &lt;strong&gt;really&lt;/strong&gt; need to go to the office
&lt;/h3&gt;

&lt;p&gt;As I write this, nothing comes to mind as a good reason to be in the office while sick. But life is full of surprises, isn't it? If you must be sick in the office, take every possible precaution to mitigate the risk of spreading the illness or worsening your health.&lt;/p&gt;

&lt;p&gt;During my trip to Asia, I had the opportunity to observe their culture. In Europe, we're bombarded with images of people wearing masks on the streets. In reality, people wear single-use masks primarily when &lt;strong&gt;they&lt;/strong&gt; feel unwell. This way, they reduce the risk of making others sick when sneezing or talking. Unfortunately, I haven't noticed this habit in Poland. So, I want to encourage you: &lt;strong&gt;wear a sanitary mask in public places every time you feel sick&lt;/strong&gt;. You'll be grateful if your neighbors and coworkers do the same.&lt;/p&gt;

&lt;p&gt;Last but definitely not least, I urge you to &lt;strong&gt;wash your hands&lt;/strong&gt;. I don’t mean the 0.000001-second splash of water that I sometimes hear, which terrifies me. Every time you leave the restroom, put something in the recycling bin, clean up, or come indoors – wash your hands. This practice can prevent you from getting sick while touching your face and keeps bacteria from spreading on various surfaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  But business is business!
&lt;/h3&gt;

&lt;p&gt;You just read how I encourage people to stay home, but it’s equally true that all company members are responsible for the success and achievement of business goals. So, how can we find a compromise between these two?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Take care of the remote work culture.&lt;/strong&gt;&lt;br&gt;
If you don't set any rules for remote work and treat remote days as exceptions, it is likely to result in mistakes that could harm the business. Even if your company operates in a field where remote work is challenging, you'll need to prepare for that possibility. Improving your communication flow is essential. Encourage coworkers to keep files organized and in a known location. Always confirm important decisions in writing (this has saved my life a million times). Consider the overall project management flow and identify areas for improvement. Ensure that there are no "information gaps" (e.g., does it happen that someone was supposed to relay information but failed to do so? Was any important info lost?).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Risk of making sick more coworkers than already are is not worth it.&lt;/strong&gt;&lt;br&gt;
Feeling frustrated because a customer is pressuring you while a team member is sick is pointless. Even if that person tries to work, they likely won't be effective anyway. Furthermore, you risk temporarily losing more team members, multiplying the problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Happy worker is efficient worker.&lt;/strong&gt;&lt;br&gt;
Maintaining good relationships with your coworkers makes it easier to manage projects and achieve success. If someone is grateful and happy, they will do their best to compensate for any inconveniences.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Know your team.&lt;/strong&gt;&lt;br&gt;
Sometimes, some employees take sick leave often just to avoid responsibilities. If you notice that a team member is absent more frequently than others, it might indicate an underlying issue. Pressuring that person to come to the office may just worsen the situation. Instead, try to identify the real problem and work on a solution together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customers are also human :)&lt;/strong&gt;&lt;br&gt;
While there are situations where significant amounts of money depend on project success or deadlines, we often imagine customers being angry with us. In reality, customers are human beings too; they may catch the flu and will likely understand your situation. Postponing a deadline by three days will probably be easier to manage than making a coworker unhappy or possibly making your customer sick (as discussed earlier regarding meetings).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  We have just one health
&lt;/h3&gt;

&lt;p&gt;In my opinion, human well-being should be our top priority. Personal health impacts all areas of our lives, including business. It is not feasible to push our bodies to the limit and expect to succeed. All the thoughts mentioned above apply to mental well-being as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrap up
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Forcing yourself or others to work can often do more harm than good.&lt;/li&gt;
&lt;li&gt;Explore the possibilities of remote work.&lt;/li&gt;
&lt;li&gt;If you must be in the office, wear a sanitary mask and maintain top-notch hygiene.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>workculture</category>
      <category>coronavirus</category>
      <category>softskills</category>
    </item>
  </channel>
</rss>
