Categories
Business

Scrum Methodology

What does it mean to be agile?

Being agile means we know how to react to the market and customers, and we react by responding quickly to their needs and requests. Agile methodologies try to minimize the risk of creating products that do not meet – or no longer meet – the needs of the market nor the customers.
Scrum is one of the most popular agile methodologies that is nowadays used to develop complex products and systems.

Agile scrum methodology is a Sprint-based project management system with the aim of providing the greatest value to stakeholders. It encourages teams to learn from experience, to self organize while working on a problem, and to reflect on their wins and losses in order to continuously improve.

It consists of 3 steps: 
1. getting work done
2. checking it
3. adjusting it

 

We ourselves use Scrum methodology for the management of our own projects, and tools such as Jira, Azure or Trello help us with the project and task organization. They are easy to use, and also let us keep track of the progress, so both we and our clients are always up to date when it comes to work that is currently being done and how its progress is coming along, so that if needed we can adapt to it in the future.

In this post, we will go through some Scrum events and Scrum participants, and what they look like for us.

Sprint

A Sprint is a time-bound period of 2 ,up to 4, weeks during which specific work must be completed and ready to be delivered to the stakeholders. This way, feedback is obtained regularly and plans for further implementation or potential changes can be made.

The duration of the Sprint depends on the size and the complexity of the project itself. Within our projects, it usually lasts for 2 weeks.

Sprint starts with Sprint Planning and ends with Sprint Review and Sprint Retrospective. These phases are repeated throughout the project’s life cycle until the entire project is delivered before the stakeholders.

Product backlog and Refinement

The Product Backlog contains all the work related to product development and its improvement. Product Backlog is a list of work tasks (Task, Story) that need to be done in order to develop the product. This list is open to change and is continuously updated as the work on the product progresses.

Refinement is a meeting in which both the Product Owner and the development team participate. They analyze, discuss, assess the complexity and time needed to complete the tasks. This is also the way of keeping Product Backlog well maintained. Work assignments must be understood by everyone involved (shared understanding), have an estimate on complexity and how much effort (time) will the implementation take.

Refinement and Sprint Planning help us prepare and plan both work tasks and Sprints better.

Sprint Planning

Sprint Planning is the event in Scrum that starts the Sprint. The purpose of Sprint Planning is to define what can be delivered within the Sprint and how will that be done. Sprint planning is done by the Product Owner in cooperation with the entire Dev team.

The estimated duration of Sprint Planning is 2 hours for each week of the Sprint. This means that if the Sprint lasts 2 weeks, this meeting should last 4 hours. But if the team prepares well and estimates the tasks they plan to include in the Sprint, planning can take less time.

Our practice is that Sprint Planning does not last longer than an hour, and we achieve this by carefully preparing and estimating each work task during the Refinement meetings.

Daily meetings

During a Sprint, the team holds daily standup meetings in order to discuss progress and find solutions for challenges we are facing. Both the Development team and Product Owner attend this meeting, although the PO is not required.

During this meeting, all team members should give answers to the following 3 questions:
1. What did you do yesterday?
2. What are you going to do today?
3. Is there something blocking you?

Daily meetings should last from 5, up to 15 minutes.
We hold them every morning, at the beginning of the work day.

Sprint Review

The Sprint Review is an informal meeting during which the team demonstrates what has been achieved, while stakeholders provide feedback. The Development team, Product Owner and Stakeholders are attending this meeting.
The main purpose of the Sprint Review is to examine the outcome of the Sprint, gather feedback from all stakeholders, create a plan and reorganize the Product Backlog.

The Sprint Review is held at the end of the Sprint. The duration of this type of meeting is estimated at 1 hour per Sprint week. This means that if the Sprint lasts 2 weeks, this meeting should last 2 hours.

We like to keep our Sprint Review flexible, therefore our Sprint Review lasts up to an hour.

Sprint Retrospective

At the Retrospective we discuss what went well during the previous Sprint and what can be improved for the next one. We can think of it as a meeting where we discuss the good and bad things that happened in the previous Sprint and the things that we should start, stop and continue doing. This is the moment when the previous Sprint is used for learning.
The meeting is attended by the Development team, Product Owner and Scrum master.

A Sprint Retrospective is held at the end of each Sprint. The estimated duration of the Retrospective is 45 minutes per Sprint week. This means that if the Sprint lasts 2 weeks, the Retrospective should last 1 hour and 30 minutes.

We believe that the time allotted for the Sprint Retrospective should be flexible. When we judge that the Sprint was easy and that we did not have any problems, we reduce the duration of the meeting.

Dev Team

Group of 3 to 9 people that are working together on development of a product, and have all the skills and abilities needed to get the development done.

In our case, a Dev team consists of 1 or more Android developers, 1 or more iOS developers, 2 backend developers (mostly), a designer and a tester.

Conclusion

We have seen what Scrum should look like theoretically, as described in the scrum guide. We also saw how we could apply the Scrum methodology and adapt it to our projects. The Scrum guide should only be a guideline on how to proceed, but the point of agile methodologies is flexibility and learning from previous experiences. That’s why if you, like us, feel that you can’t apply or do some things as described, you have the freedom to adapt them as you see fit for your own team and projects. This will bring out the best in team, as they feel free to express their opinion, approval or disapproval – and in the end, that’s how success is achieved!

Categories
Android

Troubleshooting Common Android Studio Bugs: Tips and Solutions

Here are a few common issues that users face when working with android studio, along with some potential solutions:

1. Gradle sync failed: This error often occurs when android studio is unable to download the required dependencies to build your project. To fix this, try the following steps:

  • Make sure you have a stable internet connection
  • Check your project’s build.gradle file and ensure that all dependencies are properly specified
  • In android studio, go to File > Invalidate Caches / Restart and click on “Invalidate and Restart”
  • If the issue persists, try updating android studio to the latest version

2. Emulator not starting: If your emulator is not starting or is showing an error message, try the following steps:

  • Make sure you have installed the latest version of the android emulator and have set up a virtual device
  • Check that your system has the required hardware and software specifications to run the emulator
  • In android studio, go to Tools > AVD Manager and verify that the virtual device is properly configured and working
  • If the issue persists, try restarting your computer and android studio

3. APK not installing: If you’re having trouble installing your app’s APK on a device or emulator, try the following steps:

  • Make sure your device or emulator is running the same or higher version of android as the one your app is targeting
  • In android studio, go to Build > Build Bundle(s) / APK(s) and select “Build APK(s)” to generate a new APK for your app
  • On your device or emulator, go to Settings > Security and enable “Unknown sources” to allow installation of apps from sources other than the Google Play Store
  • If the issue persists, try restarting your device or emulator and installing the APK again

I hope these suggestions are helpful in resolving your android studio bugs. If the issue persists, you may want to check the android studio community forums or contact the android studio support team for further assistance.

Categories
Android

Custom bar chart for android – tutorial

In our Skenit app, used for gym management, we wanted to improve user experience by providing them with statistics that show monthly users per gym, the number of users per training type, financial reports for every month, etc. By doing this we would give our users more insight into the gyms they own, their employees, their business growth, and income.

One of the best ways to represent this data to users is through data visualization. Data visualization offers an easy approach to observing and analyzing trends, outliers, and patterns in data by utilizing visual components like charts, graphs, and maps. Data visualization is essential to analyze massive amounts of information and allow you to make data-driven decisions that can improve your business even more. 

Using MPAndroidChart for data visualization

For this task, I have chosen MPAndroidChart which allows us to create different kinds of data visualization. This library is easy to use and charts are highly customizable, the library is well documented and there is a vast amount of implementation examples online.

In this tutorial, we will give an example of a bar chart that shows income per month, as shown on the image.

Preparation

1. Import this library into build.gradle (Module: app):

<code class="language-kotlin">dependencies {
     implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
 }</code>

2. Import this library into build.gradle (Project: …):

<code class="language-kotlin">repositories {
    maven { url 'https://jitpack.io' }
}</code>

3. Go to fragment.xml and declare the BarChart view in the layout:

<code class="language-xml">
&lt;com.github.mikephil.charting.charts.BarChart
       android:id="@+id/bar_chart
       android:layout_height="150dp"/>
</code>

Be sure to add layout_height or you won’t be able to see anything because the chart will be collapsed.

The style/look of the chart has to be made programmatically, inside of a fragment or activity.

Stylize bar chart

1. Make a function with a parameter of BarChart type. This method will determine the look of a chart and will initialize it. You can make multiple functions for different styles.

<code class="language-kotlin">private fun initializeBarChart(barChart: BarChart) {}</code>

2. Stylize the chart by adding different parameters. I recommend checking out the documentation for the list of all the parameters you can adjust. You can experiment until you get the look you want. Feel free to copy these parameters if you want the same look we have:

<code class="language-kotlin">private fun initializeBarChart(barChart: BarChart) {
   barChart.description.isEnabled = false
   barChart.axisRight.isEnabled = false
   barChart.animateY(1500)
   barChart.legend.isEnabled = false
   barChart.setTouchEnabled(false)
   barChart.xAxis.setDrawGridLines(false)
   barChart.xAxis.position = XAxis.XAxisPosition.BOTTOM
   barChart.xAxis.setDrawLabels(true)
   barChart.xAxis.granularity = 1F
   barChart.xAxis.valueFormatter = AxisFormatter()
   barChart.axisLeft.isGranularityEnabled = true
   barChart.axisLeft.axisMinimum = 0F
   barChart.axisLeft.valueFormatter = LargeValueFormatter()
}</code>

Don’t worry if AxisFormatter() and LargeValueFormatter() are red, we will solve that next.

Formatters

1. X and Y-axis inputs can only be numbers, we cannot make January an input for the X-axis. That is why we have to make an axis value formatter, and add it as a value formatter for the X-axis (barChart.xAxis.valueFormatter = AxisFormatter()). Axis formatter will change the number on the X-axis (which represents one X-axis entry) to the corresponding name of the month.

Make an inner class that extends IndexAxisValueFormatter(), and override function getAxisLabel(). This function will take input from X-axis (value) in form of a number, and get a string for it from the list of strings (monthLabels). Variable monthLabels will be populated with month names when we start iterating through our data, later in this article.

<code class="language-kotlin">val monthLabels: ArrayList<String> = ArrayList()

inner class AxisFormatter : IndexAxisValueFormatter() {
    override fun getAxisLabel(value: Float, axis: AxisBase?): String {
        val indexOfBar = value.toInt()
        return if (indexOfBar - 1 < monthLabels.size) {
            monthLabels[index - 1]
        } else {
            ""
        }
    }
}</code>

2. We also want to show the value of each bar on top of it. Make another inner class that extends ValueFormatter(), that will take the value of each bar and create a string that can be shown on top of every bar:

<code class="language-kotlin">inner class IntValueFormatter : ValueFormatter() {
    override fun getFormattedValue(value: Float): String {
        return value.toInt().toString()
    }
}</code>

Create bar chart

1. Create a function that will take data and show it in form of a bar chart. This function will take a map of String and Int, where String stands for the name of the month and Int for the income amount for that month:

<code class="language-kotlin">private fun createIncomePerMonthChart (Map<String, Int>) {}</code>

2. Declare two variables. The first variable (barChartValues) will be the list of all the bar chart entries (containing X and Y-axis values) and the second one (xAxisBarEntry) will just increment after each entry creating X-axis entry values for the first variable (barChartValues).

Function forEach will iterate through data and for each entry it will add a new BarEntry to the list, using data of each month as Y-axis values, and xAxisBarEntry value for X-axis values. It will also store the names of months in the variable monthLabels, and the AxisFormatter that we made earlier will use that variable/list to swap X-axis values with the corresponding month names.

<code class="language-kotlin">private fun createIncomePerMonthChart (incomePerMonth:  Map<String, Int>) {
    val barChartValues: ArrayList<BarEntry> = ArrayList()
    var xAxisBarEntry = 0F

        incomePerMonth.forEach { month ->
                yAxisValues.add(BarEntry(xAxisBarEntry, month.value.toFloat()))
                monthLabels.add(month)
                xAxisBarEntry++
            }
}</code>

3. Now we will pass the data to the BarDataSet (set of bars in this chart). We also have to choose a color for the bars, and in this case, we used the same color for all the bars. We also added value formatter (IntValueFormatter()) to the barDataSet so that we can see numbers on top of the bars:

<code class="language-kotlin">private fun createChart (incomePerMonth:  Map<String, Int>) {
…
val barDataSet = BarDataSet(barChartValues, "")
barDataSet.color = getColor(requireContext(), R.color.orange)
barDataSet.valueFormatter = IntValueFormatter()

val data = BarData(barDataSet)
binding.bcIncomePerMonthsEUR.data = data
binding.bcIncomePerMonthsEUR.invalidate()
}</code>

4. Initialize the bar chart in onViewCreated method. This will assign the defined style to the view from the layout:

<code class="language-kotlin">initializeBarChart(binding.barChart)</code>

5. Finally, create the bar chart by providing data to the createChart method. This method should be also called in onViewCreated method below/after the initializeBarChart method:

<code class="language-kotlin">createChart(data)</code>
Categories
All

Front-end vs. Back-end: What is the difference

Terms like front-end and back-end development may be confusing to someone who is new to the world of coding and software engineering. Let’s clear up some of the ambiguity around some of these technical phrases. We’ll explain the differences between the front-end and back-end.

Today, we’re addressing the following issues and demystifying the distinctions between development styles:

  • What is front-end development? 
  • What is back-end development? 
  • What differences exist between front-end and back-end development

Front-end development

Front-end developers create with the user in mind. Front-end development is a type of computer programming that focuses on the coding and building of website/app parts and functionality that will be visible to the user. It is focused on ensuring that the aesthetic parts of a mobile application are functioning. 

Back-end functionality in mobile apps can sometimes be stored locally rather than on the server. These programs are generally offline, which means they may be downloaded and used without an internet connection. In this case, mobile developers would be responsible for both the front-end and the back-end.

Consider the front-end to be the “client-side” of an application. Assume you’re a front-end developer. This implies that your job is to code and bring the visual parts of a mobile app to life. You’d be more concerned with what a person sees when they visit a website or utilize an app. You’d also want to make sure the user interface (UI) is simple to use and runs properly, and that the user experience (UX) is desirable.

These developers bring the visual concepts created by UX and UI designers to life, ensuring that the website or an app performs properly for the user.

Things front-end developers do:

  • Improving the user experience.
  • Creating mobile applications.
  • Bringing concepts to life with Android studio and Kotlin (for android apps), Xcode and Swift (for iOS apps), HTML, JavaScript, and CSS (for web).
  • Creating and updating the user interface.
  • Using design on mobile apps or websites.
  • Developing technologies to improve site interaction across browsers.
  • Managing the workflow of the software.
  • Following excellent SEO tactics.
  • Bug fixes and usability testing

Back-end development

Back-end development deals with the aspect of the website that visitors do not see. It is what allows a website to be interactive. The back-end of a website is sometimes known as the “server side.” 

Assume you own and operate a social networking platform. You’ll need a convenient location to save all of your users’ information. A database is a type of storage center, and some popular examples are Oracle, SQL Server, and MySQL. A database is managed by a server, which is effectively a remote computer. A back-end developer will assist in the management of this database and the site information stored on it. This guarantees that your social networking website’s front-end features continue to function properly when visitors view posted material and other user profiles.

​​While visitors do not directly contact the back-end of a website, they will interact with things that these developers are working on via a front-end application. Back-end development is concerned with storing and organizing data while also ensuring that the front-end works properly.

Things front-end developers do:

  • Database development, integration, and management
  • Frameworks for developing server-side software on the back-end
  • Technologies used in web servers
  • Integration of Cloud Computing
  • Server-side programming languages
  • System software
  • Development, deployment, and maintenance of content management systems
  • API interoperability
  • Cyber security.
  • Reporting entails the creation of analytics and data.
  • Technologies for backing up and restoring website files and databases

Front and back-end developers use different technologies

A programming language will be used while you code. These languages, like human languages, enable programmers to communicate with their computers using a set of symbols (referred to as code). Simply explained, it’s the same as giving your computer instructions. Front-end developers use programming languages such as XML, Kotlin, and Swift for mobile development, and HTML, CSS, and JavaScript for web development.

  • XML is an acronym for Extensible Markup Language.XML tags define data and are used to store and organize information. XML is utilized in Android to implement UI-related data, and it is a lightweight markup language that does not make the layout heavy.
  • Kotlin is a trendy, contemporary programming language. Kotlin may be used for server-side, client-side web, and Android programming.
  • Swift is an extremely powerful and user-friendly programming language for iOS, iPadOS, macOS, tvOS, and watchOS. Swift code is interactive and enjoyable to write, and the syntax is compact yet expressive.
  • HTML is an acronym for Hyper Text Markup Language. It is the most often used markup language for constructing web pages.
  • CSS is an acronym for Cascading Style Sheets. CSS is used to provide style and flare to a webpage, whereas HTML is used to establish structure. It specifies the colors, fonts, and style of other site content.
  • JavaScript is a programming language that may be used to make a website dynamic and entertaining. For example, you might use it to host a game on your website.

Front-end developers use their own frameworks and libraries. A front-end developer could deal with the following frameworks and libraries:

  • Native Android
  • Native iOS
  • Non-Native mobile frameworks (Swiftic, Native Scripts, React Native, Xamarin, Flutter)
  • AngularJS
  • React.js
  • jQuery
  • Sass

PHP, C++, Java, Ruby, Python, JavaScript, and Node.js are some of the languages used by back-end developers. Here’s some more information about a handful of these languages:

  • PHP is a scripting language used on the server.
  • Java is a well-known platform and computer language.
  • Python is a multi-purpose programming language. It differs from some of the others described here in that it may be used for other types of software development as well as web development.

Back-end frameworks include the following:

  • Express
  • Django
  • Rails
  • Laravel
  • Spring

Summary

Front-end development is a branch of programming that focuses on the visual parts of a website or app with which a user would interact (the client side). Meanwhile, back-end development is concerned with the aspect of a website and app that visitors do not see (the server side). They collaborate to develop dynamic websites and apps that allow users to make purchases, use contact forms, and engage in any other interactive activities while perusing a site. Netflix, PayPal, Facebook, Youtube, etc. are all instances of dynamic websites/apps.

Categories
Business

Mobile App vs. Website: What is best for your business

As a CEO or business owner, you have probably considered how to attract customers and what strategy to use, such as whether to develop a website or mobile application. There is no definitive answer because the alternative you pick will rely on your business plans, your resources, and any properties you might require.

We would like to share our expertise in this area and highlight the advantages of mobile apps to assist you in making the best decision for your company.

Numbers speak for themselves

In 2020, mobile devices accounted for 68.1% of all website visitors globally, up from 63.3% in 2019. 28.9% of visitors came from desktops, while 3.1% came from tablets.

This shows that the mobile users percentage keeps growing every year and that the future is undoubtedly mobile. On the graph below you can see that the number of mobile online users surpassed desktop users as far as in 2013. and this difference is bigger every year.

The Ideal Situation to Develop a Mobile App

There are many circumstances where creating a mobile application is the best option for addressing particular company objectives:

  1. An application would be a better solution than a website, for example, if you intend to set up features tied to native device capabilities, such as GPS, click-to-call, cameras, scanners, BlueTooth devices, etc.

  2. Another appropriate occasion to pick an application is when you’re developing a platform, like a social network or a content marketplace, that has to maintain all these components functional and dynamic and requires access to multiple sorts of content (such as images, texts, music, and Youtube videos).

  3. Applications are ideal for interactive games like Angry Birds, daily utilities like Evernote, and services that let you train, monitor your progress in real time, and receive reminders on a regular basis (FitBit, Duolingo).

  4. A mobile application is also a viable option for data manipulation. It’s also preferable to use an app for processing complex computations and creating reports, such as in banking and finance. In addition to a full website, a mobile app may be a terrific supplement for banking operations and services. Banks (such as Banca Intesa and Raiffeisen) successfully implement this concept by focusing solely on the most widely used desktop web capabilities that are essential for usage on the go and include them in their applications in a way that makes them simple and convenient to use.

Advantages of choosing an app over a website

  • Convenience. Analysis reveals that the applications are more widely used than comparable websites because they are more practical. Mobile applications are simpler to use, offer better user experiences, and load content more quickly. In addition, applications feature push alerts, unlike web pages. Within an app, communicating updates, unique features, and reminders improves user retention. Additionally, compared to websites, the design of mobile applications more gracefully adapts to various screen sizes.

  • Personalization. Apps for mobile devices are a fantastic solution for services that need frequent use. Users may configure preferences, make personal accounts, and store important information in an application. From a commercial perspective, mobile applications offer superior assistance for audience targeting and subsequently designing marketing campaigns for various user groups.

  • Working offline. The ability to utilize mobile apps offline is an additional significant benefit. Apps can continue to offer access to material and services after being downloaded and installed on a mobile device, even if there is no internet connection.
Categories
All

How to become a self-taught programmer

A lot of people these days consider a career in tech. A good salary, substantial job opportunities, a relatively low barrier to entry, and the possibility of remote work attract many people.

I know it looks scary to get into coding if you don’t have any knowledge and experience, but in reality, you need 3 to 6 months to become a “job-ready” programmer. You need almost no investment, except for your time and a few tools – a computer and a smartphone.

The first problem is deciding what career path to take. Should you get into web, mobile, frontend, backend, game development, machine learning, or blockchain? It’s hard to choose when you don’t have any knowledge. It is precisely for this reason that I wrote this article, to help you find your way and facilitate your path to success.

Where to start?

First, you should decide what technology interests you the most. It can be a couple of different technologies, and in the end, you can choose only one. If you don’t know what technology interests you, you can experiment. For example, you can try something out for a week or two and see if it looks interesting to you.

When I wanted to get into coding my interests were around the web and mobile development because I had ideas for websites and mobile apps. These ideas are going to keep you learning, they are going to give you motivation and purpose, and they are going to be the “finish line” (of your first race). Without this, you may find yourself wandering without a goal, and you can lose motivation quickly.

The second most important thing is to check for the market. You need to check if there are open job positions for the technology you want to learn. If you want to learn web or mobile development, you won’t have this problem, but if you are interested in some other technologies situation may be different.

The third thing is the size of the salary. Programmer salaries are above average, but some technologies are better paid than others.

In my situation, I have chosen mobile development (android) over web development because of three reasons:

  1. More jobs

    There are more jobs for android developers since the market is less saturated with mobile developers than web developers. You can still get a job as a web developer without a problem, but mobile developers are more in demand.

  2. More money

    Because of this scarcity of mobile developers, the salary size is much larger. Mobile developer salary is one of the bigger ones on the market, with around 50%-60% higher on average compared to web developer salary in the US.

  3. You can make a finished product

    As a mobile developer, you can make a fully functional app by yourself, front and backend, meaning that you can make a fully finished product and sell it on the market. With frontend web development you don’t have a finished product. You will either need to learn the backend and become a full stack developer, which can take a lot of time, or find someone to do the backend.


Using similar logic, you can find what suits you best.

The learning process

When you have found your desired technology, it is time to start with the learning process, which is the hardest part, because you will need around six months of learning to become a job-ready developer, and while learning, you will get no reward (pay). That‘s why many people are struggling with the motivation to learn.

Remember this: “Learning is not attained by chance, it must be sought for with ardor and attended to with diligence.”

You can only become a good developer if you learn consistently for 2-4 hours daily. It is ok to take a day or two of rest sometimes, but try to code every day if you want to get a job ASAP.

I made these four steps to follow in the learning phase that will help you become a better self-taught programmer:

  1. Start with the basics

    Learn the basics of chosen programming language, the programming paradigm used for your desired technology, design patterns, and good programming practices.

    The worst thing you can do is start working on projects without understanding these rules and principles by following a tutorial on the internet. In this case, you will end up with spaghetti code, unable to understand your code.

    In my case, for android development, I started with Java and OOP (Object Oriented Programming). I didn’t begin with android development right away. Instead, I focused on the basics of programming for the first two months.

  2. Acquire tech-specific knowledge

    When you understand the basics of a programming language and a programming paradigm, you can start learning more about the technology/niche in which you are interested.

    In this phase, I started with the basics of android development.

  3. Don’t overdo it.

    Don’t start learning for eight hours every day because you will experience burnout. Programmer burnout is emotional and mental tiredness in doing computer programming caused due to excess programming/learning.

    Do not study for more than a maximum of 4 hours a day. Even that is a lot for some people. Consistency is the key. Learn as much as you can and stay healthy, psychologically and physically.

  4. Find a mentor.

    Finding a good mentor can make learning much easier and more enjoyable. A good mentor will give you study guidelines so you don’t wander off while learning, allowing you to focus on the crucial things.

Preparing for job application

Before applying for a job you will need to be well prepared. You need to be different and noticeable to have the best chances of getting hired. These four things will be crucial:

  1. Build real-world projects that people can use.

    Many tutorials teach you how to make many useless projects instead of building a couple of useful ones. For example, if you are into web development, try to make a fully functional online store that people can potentially use.

    Tutorials from which I learned taught about making a tic-tac-toe game, weather app, quiz game, etc. These projects are ok for learning the basics but before applying for a job position, build an app that people can download on Google Play Store and use in real life. It’s better to have one app that implements a couple of libraries and has a clean architecture that is useful than to have many simple apps that are useless.

    I applied for a job with one app on the Google Play Store with MVVM architecture, SQLite database with Room persistence library, Firebase for user log-in authentication, and four basic operations of persistent storage – create, read, update, and delete (CRUD). Apart from that, I had two basic apps that showed I could use Google Maps API and a weather app that showed I could work with JSON.

  2. Make a CV that stands out.

    If your CV sucks, even though you are an “awesome” programmer, you will not get almost any interviews.

    Find tips on how to write a good CV that stands out. I suggest you also check out CV-making platforms like resume.io.

  3. Make a personal portfolio website.

    I recommend checking out GitHub Pages. Here you can host a website for free.

  4. Optimize LinkedIn profile

    And last but not least, make an optimized LinkedIn profile. You can find tips on how to make a good LinkedIn profile online.

    This is important since you will also apply for jobs on this platform. Also, recruiters can find you here and contact you even before you apply for a job, and a professional-looking profile will show that you are serious and active.

Applying for a job

When you are finally ready, you can start applying. You will probably still think you are not good enough, but if you managed to finish all previous tasks, you are ready. You are applying for a junior developer position without work experience, no one is expecting you to know everything. You must have a solid foundational understanding of programming in general and your specific technology. The learning process will begin when you start working on large-scale projects in a team at your first job.

You will probably feel anxiety when you get your first interview. But trust me, there is nothing to be afraid of. Try to learn from your interviews, and don’t give up until you get a job, even if it takes a lot of failed interviews.

Here are some tips to help you get a job:

1. Apply to all job postings (for your tech niche).

If there are 50, 100, 200, or even more job postings, apply to all of them, and remember to make a list of companies you applied to. Many companies will not respond to your application at all, and some will respond to you after several days, weeks, or months.

I applied to around 50 different job postings and got around 15 interviews.


2. Again, apply to all job postings.

Even if you are a junior developer, you should apply to job postings for mid and senior-level developers.

Some companies responded to my application after some time saying that they have an open junior developer position.


3. Be communicative and confident, and express your ideas during interviews.

Feeling confident – or pretending that you feel confident – is necessary to reach for opportunities. It’s a cliché, but opportunities are rarely offered; they’re seized. – Sheryl Sandberg, Chief Operating Officer of Facebook

You may think that interviewers will mainly value your coding skills. But they are looking for a person that is ready to grow and learn, can work in a team, and can contribute with their ideas.

4. Failure is not an option

Don’t give up if the first couple of interviews doesn’t go well. Use failure to identify where you could use some improvement. Do whatever it takes to get your first job. Improvise. Adapt. Overcome.

Reaching your goal or just starting an adventure.

You might think you’ve reached your goal when you get your first job. But the truth is that getting a job is just your first step.

Try to enjoy this neverending growing process and use your newly acquired skills to improve your life and make the world a better place for everyone.

“Also, don’t forget that some of the most successful people in the world are self-taught programmers. Steve Wozniak, the founder of Apple, is a self-taught programmer. So is Margaret Hamilton, who received the Presidential Medal of Freedom for her work on NASA’s Apollo Moon missions; David Karp, founder of Tumblr; Jack Dorsey, founder of Twitter; and Kevin Systrom, founder of Instagram.”
― Cory Althoff, The Self-Taught Programmer: The Definitive Guide to Programming Professionally

Categories
iOS

How to fix missing dSYM files on Firebase Crashlytics

So you decided to set up Firebase Crashlytics on your iOS app to be able to track any crashes that may occur, either while testing or in production. You followed the Firebase documentation step by step and did everything correctly. You forced a crash and it appeared on the Firebase console? Great.

You uploaded the app on TestFlight and told your testers to start testing. After some time, you open the Firebase console and notice that there were no crashes recorded and you see a big red sign telling you that you have to upload dSYM files to be able to process those crashes.

But how are you going to do that?

Let’s first explain what a dSYM file is.

Firstly, when Xcode compiles source code to machine code it generates a list of symbols (class names, global variables, method, and function names). That symbol and the information about the file name and the line number where the symbol is declared constitute a debug symbol. Those debug symbols are used both by the Xcode debugger and for generating the crash reports. When you create a debug build these debug symbols are contained inside the compiled binary file.

Archiving an app

When you create a release build (when you archive an app) debug symbols are placed in a dSYM (Debug Symbol) file to reduce the size of the app. Each binary file (main app executable, frameworks, and app extensions) in an app contains its dSYM file. The binary file and its corresponding dSYM file are tied together by a build UUID. This build UUID is unique, even when the same source code gets compiled with a different Xcode version or build settings, a different UUID will get generated. dSYM files are not the only symbol files. When you archive an app with bitcode, the symbols in the dSYM files are replaced by obfuscated symbols to provide privacy for symbol names. A new symbol file bcsymbolmap (bitcode symbol map) gets created and its purpose is to translate these hidden symbol names back to the original symbol names.

Uploading app to the app store

When you upload an app to the app store it is uploaded as a bitcode. Bitcode is an intermediate representation of how the code looks. That bitcode is later converted to an app binary by Apple. Those new binaries now have different UUIDs than dSYMs that were uploaded to Firebase during build time. So new dSYM files get created and we have to manually upload them to Firebase.

How to fix

1. Open Firebase Console and see for what build should you upload the dSYM files

2. Open that build on App Store Connect 

3. Open build metadata, under General Information find the Includes Symbols tab and click on Download dSYM

4. Unzip the downloaded file

5. Write down the paths for the Pods folder of your application, GoogleService-Info.plst file, and the downloaded dSYMs folder

6. Open the terminal and execute the following command

/path/to/pods/directory/FirebaseCrashlytics/upload-symbols-gsp /path/to/GoogleService-Info.plist -p ios /path/to/dSYMs

7.  If you’ve written the command correctly there should be no warnings and errors and the console should output UUIDs of all the dSYM files that have been uploaded. You can check if they match with the ones in your Firebase console.

8. Wait a couple of minutes for Firebase to process the files

And voila, all the crashes should be displayed on the console.

These are the sources I used in the making of this tutorial, hope you found it useful:

https://developer.apple.com/documentation/xcode/building_your_app_to_include_debugging_information

https://www.tutorialspoint.com/what-is-embedded-bitcode-and-what-does-enable-bitcode-do-in-xcode

https://stackoverflow.com/questions/34363485/why-does-recompiling-from-bitcode-make-me-unable-to-symbolicate-in-xcode-ad-hoc

https://stackoverflow.com/questions/54577202/how-to-run-upload-symbols-to-upload-dsyms-as-a-part-of-xcode-build-process

Until the next read, stay well and safe.

Categories
iOS

How to create a QR code widget

Yes, the long-awaited widgets for iOS devices are finally here!

After the big announcement made at Worldwide Developers Conference in June 2020, Apple has released its biggest update regarding the iOS operating system in September 2020 – iOS 14, with the amazing feature that allows its users to create and add widgets to the home screen of their device.

Hoping that we are not joining the party too late, we decided to try it out ourselves and share our thoughts on the way. In this example, we’ll cover how to add a QR code to the widget that can, later on, be used to present any type of data, be it a link or a plain string message.

But wait. Before you sit down and start developing your widget, there are two requirements you need to know about.

  1. Your device or simulator has to run the iOS 14 operating system
  2. Your Xcode has to be updated to version 12.1

Also, note that we used a third-party library to generate the QR code.

Said that, let’s get started on the widget.

Setup

First things first, you will need to add a new target to the project, by clicking on File > New > Target and choose Widget Extension in the iOS tab, as done in the photo below.

After creating the new target it’s time to add the QR code library to the widget extension. I found that the best way to do that was to add the library using the Swift Package Manager. To do so, select your project in the project navigator and switch to the Swift Packages tab. By clicking the + button you will be asked to add the package repository URL (that can be found on the library’s GitHub in the installation section). The last step to incorporate the QR code library to the widget extension is to go to its target, click the + button in the Frameworks and Libraries section and choose it from the suggested list of libraries. 

Implementation

Moving on, we’ll go to the Widget.swift file where we’ll implement the presentation of the QR code on the widget itself. The first thing you may notice about this class is that the code is written in SwiftUI. Keep in mind that even if you haven’t had a chance to cross paths with SwiftUI before, you won’t need to make big changes to the code.

At the top of the class import your QR code library. Find the WidgetEntryView struct and delete the entire code leaving only the entry property and body view. For this example, we used the EFQRCode library for QR code generation. The QR code library creates image of type cgImage, so we created an additional method that allows us to generate the QR code and parse it to the type of UIImage, making it easier to work with and therefore show on the widget.

The last, but not least step is to use the newly generated QR Code image in the body. The resulting code is shown below.

Result

It’s time to see what we’ve done! 

Run your app on the simulator or device, and once it’s running, close it. Press and hold the screen until the apps on your home screen start to jiggle and the subtle + button appears in one of the top corners. Click on it and the new screen will be presented to you, holding all of the disposable widgets on the phone. Find the widget with the QR code, or in case it is not there find the name of your app, choose the size that fits your screen, and voilà! Your widget is done and ready to use.

Categories
All

Stateful vs. stateless widget

Welcome to the widget class

Creating flutter UI can be demanding. But you’re in luck, you have your greatest helper, the Widget class, here to help you!

In the world of flutter UI, everything is a widget. Widget is the primary building block of the Flutter UI. Widget is an immutable description of part of a user interface, which means all their fields must be final. By themselves, widgets have no mutable state.

What are stateless and stateful widgets?

A stateful widget is a widget that has a mutable state associated with it. Associating a mutable state to a widget like this gives the app interactivity and responsiveness. Without stateful widgets, we wouldn’t be able to do something like this in the images below:

Here, we can change the border of the card and replace the text in it with a nice checkmark, pointing out that the card is selected.

On the one hand, stateless widgets don’t have a state associated with them. This means that when a stateless widget is built, it cannot be changed unless we create a whole new instance of that widget. On the other hand, stateful widgets can be rebuilt any number of times, just call setState, and in the body of setState put the code that affects the UI.

Stateless widgets when created look like this:

<code class="language-dart">
 class StatelessExample extends StatelessWidget {
                @override
                Widget build(BuildContext context) {
                               return Text("This is a stateless widget");
                }
 } 
</code>

… While stateful widgets look like this:

<code class="language-dart">
 class StatefulExample extends StatefulWidget {
                @override
                State createState() => _StatefulExampleState();
 }
  
 class _StatefulExampleState extends State&#60;StatefulExample&#62; {
                @override
                Widget build(BuildContext context) {
                               return Text("This is a stateful widget");
                }
 }
</code>

For example, if we wanted to implement the Selected functionality shown in the images above, we would need to have a variable in our stateful widget, _isSelected.

All that is left is for us to call setState in the onPressed method of the widget surrounding the card body (in this example, the surrounding widget is InkWell, but it can be done with GestureDetector):

<code class="language-dart">
 onPressed: () {
                setState((){
                               _isSelected= true;           
                });
 }
</code>

The other option is to do something in the lines of this:

<code class="language-dart">
 onPressed: () {
                _isSelected = true;          
                setState((){
                });
 }
</code>

I have to mention that the first way is better because it tells you exactly what’s going on and what you are changing when calling the rebuild method, setState. With that in mind, it should be used only to wrap the actual changes to the state, not any computation that might be associated with the change.

Flutter UI hierarchy and setState

Flutter’s UI hierarchy is based on a widget tree. Every time we create a new instance of a widget, it is added to the widget tree as a child of the widget from which it was instantiated. Because of this, calling setState can sometimes be really costly. When we call setState, it does call the build method of the widget, but it rebuilds the whole subtree beneath that widget. In other words, it calls the build method of all of its children, too. If the subtree beneath it is deep, that setState can end up being costly. That is why it’s good practice to always keep the whole widget tree relatively shallow, so you don’t have to worry about costly rebuilds.

To sum things up…

… If the main idea you got out of this article is that stateless widgets are used to create UI that does not depend on the input of the user and that stateful widgets are used for creating dynamic UI, you can give yourself a pat on the back! You did well and made the first step to understanding how flutter works!

Categories
Android

How to update fragments in the ViewPager?

Five indubitably easy steps

The problem described in the title below is found to be a very common problem Android developers face. As being so, I decided that is the problem I want to dedicate my first blog post to. In this quick read, I will show and explain to you a very simple solution.

When I was first encountered with this implementation, I failed to find much regarding it while searching the internet. What was offered in response either sounded like a very poor implementation or was quite complicated to deal with.

At that time I was on a project where I had to use EventBus library, and it proved to be a very good solution, with not so demanding implementation. That is why I decided to approach the solution in this way.

A sample project for this tutorial can be found on Github repository: https://github.com/Crystal-Pigeon/photo-manipulation.

To start the implementation, we need to add the following line of code to the build.gradle file:
<code class="language-kotlin">
implementation 'org.greenrobot:eventbus:3.2.0'
</code>

We start from the fact that we have one activity, in my case that was MainActivity. It contains a ViewPager with 3 tabs, which means that we have 3 fragments and a field for entering a query, which is going to be used for the search of the data from the aforementioned fragments. To display the data each of the fragments contains a RecyclerView.

Then we need to create an event that will be observed. We create a SearchEvent class that includes the following:
<code class="language-kotlin">
class SearchEvent(var query: String, var pageTitle: CharSequence?)
</code>
The next step is to create a Publisher that will broadcast the event itself.

In this case, the event is broadcasted every time something is entered in the search field. First, we create an object of class SearchEvent and broadcast the event to which we forward the created object.

<code class="language-kotlin">
et_search.doAfterTextChanged {
      val searchEvent = SearchEvent(
            et_search.text.toString(),
            searchViewPagerAdapter.getPageTitle(vp_search.currentItem)
      )
      EventBus.getDefault().post(searchEvent) //publish the event
}
</code>
Moving forward, it is necessary to register the Bus in fragments.

We will do this by overriding the onStart and onStop methods as follows:

<code class="language-kotlin">
override fun onStart() {
    super.onStart()
    if(!EventBus.getDefault().isRegistered(this)) {
        EventBus.getDefault().register(this)
    }
}

override fun onStop() {
    super.onStop()
    EventBus.getDefault().unregister(this)
}
</code>
In addition to this, it is necessary to create a Subscriber.

Specifically, we have to create a method that needs to be annotated with Subscribe, which, as a parameter takes in an object of the SearchEvent class, that we previously created. This method is executed after the broadcast of each event.

<code class="language-kotlin">
@Subscribe(threadMode = ThreadMode.MAIN)
fun onSearchEvent(searchEvent: SearchEvent) {
    // add here what needs to happen, for example display data on the screen
}
</code>

I hope you found this solution-based summary useful, and good luck with the forthcoming work.