CategoriesiOSProgrammingSwift

Leverage MVC Pattern in iOS

Introduction

MVC (Model-View-Controller) adalah salah satu architecture pattern yang menjadi base dari projek baru dari iOS. Saya cukup yakin jika semua iOS developer tentunya tahu dengan pattern ini. Secara umum MVC terdiri 3 komponen yaitu:

  1. Model
    Komponen atau layer ini berisi data model aplikasi, networking service, data persistence dll. Intinya komponen ini berisi logik yang berhubungan data yang ada pada aplikasi kita.
  2. View
    Untuk komponen ini sendiri pastinya kita sudah tahu yaitu Storyboard yang berfungsi untuk membuat view dari aplikasi kita.
  3. Controller
    Komponen ini biasanya kita sebut dengan ViewController, yang berfungsi menjadi jembatan antara model dan view. Di mana controller ini bertugas untuk memanggil data dan mengupdatenya ke dalam view, atau mengirim sebuah respon atau action ketika view seperti button, textfield dll mengalami perubahaan state.

Problem

Untuk architecture ini sendiri menurut saya sangat cocok untuk aplikasi yang masih sederhana, namun kenyataannya implementasi yang ada masih salah. Biasanya dalam project yang ada, kita selalu menempatkan semua logic yang ada dalam ViewController bukan? Biasanya untuk melakukan fetching data, maka kita memanggil Singleton ke dalam ViewController yang ada. Sehingga yang ada bukanlah MVC(Model-View-Controller), melainkan Massive View Controller.

Beberapa masalah yang terjadi:

  1. Menyalahi aturan Single Responsibility Principle di mana ViewController menghandle terlalu banyak operasi, ViewController seharusnya hanya bertugas untuk memanggil dan melakukan update.
  2. ViewController seharusnya tidak mengetahui implementasi detail dari operasi tersebut, dalam kasus ini kita telah menyalahi aturan dari Dependency Inversion Principle, “Module shoud not depend on Detail/Implementation (Concrete Class), it should depend on abstraction”. Dengan menyalahi aturan tersebut, class ViewController menjadi Tighly Couple dengan Singleton yang ada, dan menyebabkan kode yang ada susah untuk ditest.

Nah untuk mengatasi hal tersebut tidaklah susah, kita cukup memanfaatkan Dependency Injection dan mengikuti aturan Dependency Inversion. Ayo kita langsung hands-on aja.

Starter Project
https://github.com/windywu812/BetterMVC

Hands-On

Silahkan membuka branch Main, aplikasi ini ialah aplikasi sederhana yang memuat games dari API dan menampilkannya pada tableview yang ada. Struktur kode tersebut merupakan struktur kode yang sering kita lihat dalam beberapa project. Secara sekilas struktur kode yang ada sudah cukup rapi, namun masih dapat dikembangkan. Dalam kode ini, ViewController masih bergantung pada class NetworkService, sehingga ketika membuat test kita harus menguji implementasi yang asli (memanggil data langsung) yang biasanya memakan waktu cukup lama, padahal sebuah UnitTesting harus berjalan dengan cepat.

1. Mendefine sebuah Protocol

Membuat sebuah protocol, nantinya ViewController akan bergantung pada protocol ini (abstraction), bukan class NetworkService(Concrete Type) secara langsung.

2. Membuat class yang akan mengimplementasi protocol tersebut

Sekarang kode pada fungsi getAllGames pada class ViewController dapat dipindahkan ke dalam class GameImplementation ini.

3. Refactor kode pada class ViewController

Menambah sebuah dependency yaitu GameProtocol(Abstraction) tersebut dan menghandle completion dari fungsi getAllGames

Unit Test

Dengan membuat kode kita menjadi seperti ini, maka kita akan dapat melakukan test dengan mudah dan cepat.

1. Membuat Mock Object

Dengan membuat mock object, kita tidak perlu lagi melakukan test dengan real APICall. Kita dapat membuat data dummy kita sendiri

2. Write Unit Test

Karena ViewController bergantung dengan abstraction, kita dapat dengan mudah untuk mengganti dependency yang ada. Di sini kita tidak lagi menggunakan class GameImplementation, melainkan MockGameImplementation yang berisi data dummy kita.

Kesimpulan

Dengan membuat kode seperti ini, kita dapat membuat class/kode memiliki ruang untuk bernafas yaitu tidak bergantung pada class tertentu (Loose Coupling). Unit Test yang ditulis dapat dijalankan dengan cepat dan secara offline. Jika kita mengetest dengan memanggil API Call secara langsung, maka beberapa masalah yang dapat terjadi ialah:

  1. Masalah Internet yang sangat mempengaruhi kecepatan Unit Testing kita, sehingga hasil yang ada tidak konsisten. Apalagi jika kita berada di jangkauan yang tidak memiliki sinyal internet, maka kita tidak dapat melakuakan test. Test yang ada juga relative cepat yaitu hanya memerlukan waktu sekitar 0.1 detik, jika dibandingkan dengan ApiCall yang asli maka akan membutuhkan waktu beberapa detik.
  2. Kendala terhadap API Call limit pada beberapa API, sehingga akan menghambat proses development yang ada

Untuk melihat hasil akhir, Anda bisa checkout ke dalam branch Final. Semoga dapat memberikan insight baru dan dapat bermanfaat bagi teman-teman.

CategoriesAndroidAutomated testProgramming

Unit Testing pada Aplikasi Android

Saat ngoding kita tentu harus menguji kodingan kita terlebih dahulu agar kita bisa tau kodingan kita benar atau error. tidak terkecuali saat ngoding aplikasi Android. mungkin kebanyakan dari kita melakukan pengujian aplikasi Android secara manual dengan melakukan prosedur yang telah kita tentukan secara berulang ulang, hal ini sebenarnya cukup melelahkan dan seringkali membuat kita jenuh.

Continue reading
CategoriesAutomated testsProgramming

API testing menggunakan Mocha & Chai

Diskripsi singkat

Hai gaes pasti kalian sudah familiar kan dengan API itu apa? Jadi secara singkatnya API itu adalah seperangkat aplikasi yang bisa berbentuk fungsi, method atau URL endpoint yang dapat kita gunakan untuk mengembangkan aplikasi, baik dalam satu platform maupun lintas platform. 

Terus mocha dan chai ini apa sama? jadi gini mocha itu adalah javascript library testing dan Chai sendiri adalah library yang digunakan untuk memudahkan Mocha dalam melakukan assertion pada setiap API yang dipanggil. Nah gimana udah paham kan? sekarang kita eksekusi yok gimana cara pakai mocha dan chai nya. 

 

Persiapan 

Pastikan kalian sudah menginstal nodejs, jika belum terinstall silakan install dulu disini! 

Continue reading

CategoriesProgramming

Memahami Synchronous dan Asynchronous dalam Pemrograman

         Pertama kali saya terjun di dunia kerja langsung menghadapi banyak materi yang asing. Namun materi pertama dan selalu saya gunakan sampai sekarang adalah suatu proses menjalankan aplikasi dan proses jalannya secara client dan server side, hal utama yang menurut saya perlu dipelajari adalah  Synchronus dan Asynchronus. Materi ini menurut saya sangat diperlukan untuk dasar pemrograman (walaupun saat kuliah tidak pernah ada :3). Walaupun secara tidak langsung hampir semua Web Developers  menggunakannya namun perlu Pengetahuan lebih dalam karena proses ini sederhana dan berdampak ke semua aspek kehidupan program Anda.

Apakah yang di maksud dengan Synchronouse?

Synchronous adalah proses jalannya program secara sequential , disini yang dimaksud sequential ada berdasarkan antrian ekseskusi program. Pada dasarnya semua Bahasa pemrograman menggunakan Asynchronouse terutama PHP.

Cotoh Synchronous di Bahasa Perograman PHP:

beri nama file synchronous.php
<?php
$now = date(‘Y-m-d’);
// antrian 1
echo $now.‘ |’;
$yesterday = date(‘Y-m-d’,strtotime(‘-1 days’));
// antrian 2
echo $yesterday.‘ |’;
$week = date(‘Y-m-d’,strtotime(‘-1 week’));
// antrian 3
echo $week.‘ |’;
?>
Hasil Eksekusi:
Hasil eksekusi file php sync
Penjelasan: Pada saat file synchronouse.php dieksekusi maka proses nya adalah membaca antrian 1 terlebih dahulu kemudian antrian 2 dan terakhir adalah antrian 3.

Apakah yang dimaksud dengan Asynchronous?

Asynchronous adalah proses jalannya program bisa dilakukan secara bersamaan tanpa harus menunggu proses antrian. Synchronous merupakan bagian dari Asynchronous (1 antrian) dimana proses akan dieksekusi secara bersamaan dan untuk hasil tergantung lama proses suatu fungsi synchronous . Asynchronouse hampir disemua Bahasa pemrograman ada namun untuk PHP masih belum ada. PHP sebagai server side hanya menyediakan synchronous namun bisanya di WEB Developers tetap digunakan namun menggunakan AJAX (Asynchronous Javascript And XML) untuk proses Asynchronouse.

Contoh Asynchronouse PHP + AJAX

Buat file HTML+CSS+AJAX dengan nama test.html

<style type=“text/css”>
  #sync
{
  width100px;
  height100px;
  backgroundred;
  -moz-border-radius50px;
  -webkit-border-radius50px;
  border-radius50px;
  float:left;
  margin:5px;
}
.one
{
  line-height100px;
  color:white;
  margin-left:30px;
  font-size:25px;
}
.two
{
  line-height100px;
  color:white;
  margin-left:30px;
  font-size:25px;
}
</style>
<div id=“sync”><span class=“one”>0</span></div>
<div id=“sync”><span class=“two”>0</span></div>
<br />
<script src=“https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js” 
type=“text/javascript”></script>
<script type=“text/javascript”>
  $.ajax({
        url: ‘syncronous.php?1’,
        type: “GET”,
        success: function(result)
        {
          $(‘.one’).html(result);
          $(‘.one’).each(function () {
              $(this).prop(‘Counter’,0).animate({
                  Counter: $(this).text()
              }, {
                  duration: 4000,
                  easing: ‘swing’,
                  step: function (now) {
                      $(this).text(Math.ceil(now));
                  }
              });
          });
        }
      });
  $.ajax({
        url: ‘syncronous.php?2’,
        type: “GET”,
        success: function(result)
        {
          $(‘.two’).html(result);
          $(‘.two’).each(function () {
              $(this).prop(‘Counter’,0).animate({
                  Counter: $(this).text()
              }, {
                  duration: 4000,
                  easing: ‘swing’,
                  step: function (now) {
                      $(this).text(Math.ceil(now));
                  }
              });
          });
        }
      });
  
</script>
Buat file PHP dengan nama syncronous.php
<?php
if(isset($_GET[“1”])){
    
    echo json_encode(20000);
if(isset($_GET[“2”])){
    
    echo json_encode(40000);
}
?>
 Hasil Eksekusi:
Nilai terus berjalan Secara bersamaan tanpa ada Antrian
Penjelasan: Counter Nilai terus berjalan tanpa  ada antrian.
Berikut Source Code Link Gitlab apabila anda ingin mencoba: Link

Contoh Asynchronous di NODE JS

Di artikel saya sebelumnya pernah membahas chat menggunakan Socket.io dimana basic dari Realtime Chat dengan socket.IO ada Synchronous. Silahkan lihat di Artikel saya berikut : Realtime Chat dengan Html, Javascript dan Socket.io

Note: Synchronous  dan Asynchronous saling berkisambungan jadi apabila anda ingin lebih detail bisa Anda pahami lebih dalam. Kegunakan juga sesuai kebutuhan.

Semangat Belajar!!
Wassalamualaikum..

CategoriesProgramming

Realtime Chat dengan Html, Javascript dan Socket.io

Realtime Chat atau Realtime Data sering disebut dalam dunia programing adalah suatu hal akan sering digunakan dan sangat diperlukan. Dalam kesempatan ini kita akan membahas dan langsung mem praktik kan Realtime Data dengan Chat App.

Senjata yang akan kita gunakan adalah:

1. HTML

     Sebuah bahasa markah yang digunakan untuk membuat sebuah halaman web. Platform umum yang sering digunakan sehingga akan mudah untuk di praktik kan.

2. Javascript

     Javascript adalah bahasa pemrograman tingkat tinggi dan dinamis. JavaScript biasanya digunakan untuk olah data secara Client ke server namun juga bisa sebagai server ke client. Disini Javascript akan berfungsi GET POST data dari client atau HTML.

3. Socket.io

Apa itu Socket.Io?
Socket.io ada suatu library dari Node.JS yang berfungsi untuk menjembatani realtime data, Namun jangan salah socket.io tidak hanya bisa digunakan di Node.js. Socket.io bisa digunakan di multiplatform dan yang Paling penting Gratis tanpa Batasan jumlah / Unlimited.

Silahkan Berkenalan dengan Socket.io Disini : https://socket.io/

Ayo kita praktikan secara langsung:

1. Buat file index.html.

2. Initialisasi dahulu package.json di terminal.

   $npm init

3. Install socket.io dalam depedencies

$ npm i socket.io

4. install nodemon dalam dependencies, nodemon berfungsi untuk menjalankan Server socket.io.

$npm i --save-dev nodemon

5. Set devStart di package.json untuk menjalankan server nodemon.

"devStart": "nodemon server.js"
{
  “name”“socket.io”,
  “version”“1.0.0”,
  “description”“”,
  “main”“index.js”,
  “scripts”: {
    “devStart”“nodemon server.js”
  },
  “author”“Dhendik”,
  “license”“ISC”,
  “dependencies”: {
    “socket.io”“^2.3.0”
  },
  “devDependencies”: {
    “nodemon”“^2.0.3”
  }
}

 

6. Coding script di Index.html.

<!DOCTYPE html>
<html lang=“en”>
<head>
  <meta charset=“UTF-8”>
  <meta name=“viewport” content=“width=device-width, initial-scale=1.0”>
  <meta http-equiv=“X-UA-Compatible” content=“ie=edge”>
  <title>Realtime Chat</title>
  <script defer src=“http://localhost:3000/socket.io/socket.io.js”></script>
  <script defer src=“client.js”></script>
  <style>
    body {
      padding0;
      margin0;
      displayflex;
      justify-contentcenter;
    }
    #message-container {
      width80%;
      max-width1200px;
    }
    #message-container div {
      background-color#CCC;
      padding5px;
    }
    #message-container div:nth-child(2n) {
      background-color#FFF;
    }
    #send-container {
      positionfixed;
      padding-bottom30px;
      bottom0;
      background-colorwhite;
      max-width1200px;
      width80%;
      displayflex;
    }
    #message-input {
      flex-grow1;
    }
  </style>
</head>
<body>
  <div id=“message-container”></div>
  <form id=“send-container”>
    <input type=“text” id=“message-input”>
    <button type=“submit” id=“send-button”>Send</button>
  </form>
</body>
</html>

 

7. Buat Server dahulu server.js untuk initialisasi socket.io.

const io = require(‘socket.io’)(3000)
const users = {}
// Register User yang baru Masuk ke server dan melakukan Join
io.on(‘connection’socket => {
  socket.on(‘new-user’name => {
    users[socket.id] = name
    socket.broadcast.emit(‘user-connected’name)
  })
  socket.on(‘send-chat-message’message => {
    socket.broadcast.emit(‘chat-message’,
message: messagename: users[socket.id] })
  })
  socket.on(‘disconnect’, () => {
    socket.broadcast.emit(‘user-disconnected’users[socket.id])
    delete users[socket.id]
  })
})
 

 

8. Buat client dahulu client.js disini menggunakan Javascript untuk GET POST data di HTML.

const socket = io(‘http://localhost:3000’)
const messageContainer = document.getElementById(‘message-container’)
const messageForm = document.getElementById(‘send-container’)
const messageInput = document.getElementById(‘message-input’)
//Client script untuk register User Baru
const name = prompt(‘What is your name?’)
appendMessage(‘You joined’)
socket.emit(‘new-user’name)
//Chat message client / User
socket.on(‘chat-message’data => {
  appendMessage(`${data.name}${data.message}`)
})
//Chat message pertanda user baru join
socket.on(‘user-connected’name => {
  appendMessage(`${name} connected`)
})
//Chat Message pertanda User disconnected
socket.on(‘user-disconnected’name => {
  appendMessage(`${name} disconnected`)
})
//Event post untuk Submit Message
messageForm.addEventListener(‘submit’e => {
  e.preventDefault()
  const message = messageInput.value
  appendMessage(`You: ${message}`)
  socket.emit(‘send-chat-message’message)
  messageInput.value = 
})
//Event get misal ada message Baru dari User Lain 
function appendMessage(message) {
  const messageElement = document.createElement(‘div’)
  messageElement.innerText = message
  messageContainer.append(messageElement)
}

 

9. Jalankan Server socket.io

$npm run devStart

10. Berikut Hasilnya.  Gambar dibawah menunjukan simulasi chat dari 2 User yang berbeda dan bisa Realtime.

Gmbar ini menunjukan simulasi chat dari 2 User yang berbeda

Jika ingin mencoba sendiri Anda bisa Clone Git dan ikuti arahannya: https://gitlab.com/Sendok/realtimechat.git

Sekian artikel yg bisa dibuat semoga bermanfaat.

Wassalamualaikum.