Criando um APP com Ionic 2 + Rails 5 API

post-rails-ionic2
Introdução 🙂

Criar Apps se tornou uma tarefa fácil através do uso de alguns frameworks como o Ionic 2 e o Rails 5 (para a criação da API que vai alimentar o APP). Então nesse tutorial nós vamos criar uma pequena API RAILS 5 e um App Ionic 2 que juntos vão permitir que um usuário tire uma foto e compartilhe com pessoas aleatórias do mundo através do seu mobile.

O que vamos aprender
  1. Como criar uma API com Rails 5
  2. Como receber imagens base 64 na sua API
  3. Como armazenar nossas imagens no cloudinary
  4. Como subir nossa API para o Heroku
  5. Como criar um APP com Ionic 2
  6. Como tirar fotos com seu APP
  7. Como criar um provider para conversar com uma API no seu APP
  8. Como usar o Ionic View
  9. Como juntar tudo isso 🙂

Ingredientes
  • Ruby 2.3.1
  • Rails 5
  • PostgreSQL
  • Ionic 2
  • Condova (Para usar a câmera do mobile)
  • Cloudinary (cloud para imagens e vídeos)
  • Heroku (Hospedagem para nosso APP)
  • Carrierwave (Gem para fazer uploads de imagens)
  • Carrierwave base64 (Para aceitar imagens no formato base64)
  • Ionic View (para visualizar nosso APP)
Objetivos

Criar um APP onde você possa tirar uma foto do seu mobile e que ela seja adicionada à página principal com a lista das últimas 20 imagens compartilhadas anonimamente por usuários aleatórios.

Nosso APP final vai ter essa aparência:
screenshot_2016-12-17-20-41-13-473_com-ionic-viewapp

Passo a Passo
Rails 5
  1. Criar o Projeto Rails 5
  2. Gerar o scaffold
  3. Instalar o cloudinary
  4. Subir nosso App para o heroku
Ionic 2
  1. Criar nosso projeto Ionic 2
  2. Criar a estrutura do nosso projeto
  3. Conectar o projeto com a API
  4. Subir o Projeto para o Ionic View
  5. Testar nosso APP
Mãos à Obra \o/
Parte 1 – Criando a API

Agora vamos criar nossa API para receber as imagens e depois devolver as 20 últimas fotos para o usuário.

      1. Gere o projeto (vamos usar postgreSQL para poder subir no heroku free)
        1
        
        rails new randomPic --api --database=postgresql
      2. Entre no projeto
        1
        
        cd randomPic
      3. Inclua as Gems que vamos usar para subir a foto no seu Gemfile:
        1
        2
        3
        
        gem 'carrierwave'
        gem 'carrierwave-base64'
        gem 'cloudinary'
      4. Rode o bundle para instalar as Gems:
        1
        
        bundle
      5. Configure seu arquivo ‘config/database.yml’ com as credenciais para acessar o seu banco postgreSQL instalado na sua máquina. (Caso você não saiba como instalar o postgreSQL, veja aqui https://www.digitalocean.com/community/tutorials/how-to-setup-ruby-on-rails-with-postgres)
      6. Agora vamos criar nosso scaffold (ele vai gerar algumas actions a mais além de create e index que vamos usar, mas você pode removê-las)
        1
        
        rails g scaffold pic photo:string
      7. Vamos criar nosso uploader do carrierwave
        1
        
        rails generate uploader Photo
      8. Agora precisamos configurar nosso upload para que ele use o cloudinary para subir nossas fotos para a nuvem (porque o heroku não permite guardar fotos na máquina 🙁 ), no seu arquivo ‘app/uploaders/photo_uploader.rb’ substitua o conteúdo por:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        
        class PhotoUploader < CarrierWave::Uploader::Base
          include Cloudinary::CarrierWave
         
          process :convert => 'png'
         
          version :standard do
            process :resize_to_fill => [100, 150, :north]
          end
         
        end
      9. Agora vamos criar nossas credenciais no site do cloudinary para podermos usar o serviço deles, primeiro visite: http://cloudinary.com/
        cloudinary
      10. Crie uma conta no cloudinary:
        captura-de-tela-de-2016-12-17-16-29-52
      11. Pegue suas credenciais no dashboard na seção Account Details clicando do lado direito em cima no botão Download YML, ele vai baixar um arquivo chamado cloudinary.yml, coloque esse arquivo na pasta ‘config’ do seu projeto:
        captura-de-tela-de-2016-12-17-16-33-01
      12. Agora inclua o nosso uploader no model Pic em ‘app/models/pic’ substituindo o conteúdo por:
        1
        2
        3
        
        class Pic < ApplicationRecord
          mount_base64_uploader :photo, PhotoUploader
        end
      13. Vamos criar nosso banco de dados
        1
        
        rake db:create
      14. E agora vamos rodar as migrations parar criar nossa tabela nele:
        1
        
        rake db:migrate
      15. Vamos alterar nosso controller para que devolva apenas as últimas 20 fotos, no arquivo ‘app/controller/pic_controller.rb’ substitua a linha ‘@pics = Pic.all’ na action index por:
        1
        
        @pics = Pic.all.limit(20).reverse
      16. No controller PicController remova as actions show, destroy e update e o set_pic. Vamos usar apenas index e create :), no final seu controller deve ficar assim:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        
        class PicsController < ApplicationController
          # GET /pics
          def index
            @pics = Pic.all.limit(20).reverse
            render json: @pics
          end
          # POST /pics
          def create
            @pic = Pic.new(pic_params)
            if @pic.save
              render json: @pic, status: :created, location: @pic
            else
              render json: @pic.errors, status: :unprocessable_entity
            end
          end
          private
          # Only allow a trusted parameter "white list" through.
          def pic_params
            params.require(:pic).permit(:photo)
          end
        end
      17. Agora vamos configurar o CORS (*O que é CORS) para que nosso APP possa receber chamada de outros domínios, primeiro no seu Gemfile adicione:
        1
        
        gem 'rack-cors
      18. Rode o bundle, para instalar a Gem:
        1
        
        bundle
      19. Agora no arquivo config/application.rb, substitua o conteúdo por:
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        
        require_relative 'boot'
         
        require "rails"
        # Pick the frameworks you want:
        require "active_model/railtie"
        require "active_job/railtie"
        require "active_record/railtie"
        require "action_controller/railtie"
        require "action_mailer/railtie"
        require "action_view/railtie"
        require "action_cable/engine"
        # require "sprockets/railtie"
        require "rails/test_unit/railtie"
         
        # Require the gems listed in Gemfile, including any gems
        # you've limited to :test, :development, or :production.
        Bundler.require(*Rails.groups)
         
        module RandomPic
          class Application < Rails::Application
            # Settings in config/environments/* take precedence over those specified here.
            # Application configuration should go into files in config/initializers
            # -- all .rb files in that directory are automatically loaded.
         
            # Only loads a smaller set of middleware suitable for API only apps.
            # Middleware like session, flash, cookies can be added back manually.
            # Skip views, helpers and assets when generating a new resource.
            config.middleware.insert_before 0, Rack::Cors do
              allow do
                origins '*'
                resource '*', :headers => :any, :methods => [:get, :post, :options, :create]
              end
            end
            config.api_only = true
          end
        end
      20. Por último vamos subir nosso App para o heroku, vamos lá:
        a – Visite no seu browser: https://signup.heroku.com/
        b – Crie uma conta caso você não possua.
        captura-de-tela-de-2016-12-17-19-31-06
        c – Instale o heroku cli caso você não possua e faça o login (Para aprender a instalar acesse https://devcenter.heroku.com/articles/heroku-cli)
        d – Agora precisamos instalar o git no nosso repositório e fazer o commit das nossas mudanças, rode:

        1
        
        git init

        depois rode:

        1
        
        git add .

        depois rode:

        1
        
        git commit -m 'App v1'

        e – Para criar nosso projeto no heroku rode:

        1
        
        heroku create

        f – Finalmente suba seu app rodando:

        1
        
        git push heroku master

        g – Agora rode as migrations do seu projeto:

        1
        
        heroku run rake db:migrate
      21. \o/ Pronto nossa pequena e simples API está pronta para receber novas fotos e devolver uma lista com as últimas 20.
Parte 2 – Criando nosso App Ionic 
    1. Vamos começar instalando as dependências, para instalar o npm no seu sistema linux rode no console:
      1
      
      sudo apt-get install npm

      Ou caso você esteja no Mac, rode:

      1
      
      brew install node
    2. Agora para instalar o ionic e o cordova, rode no seu console:
      1
      
      sudo npm install -g ionic cordova --allow-root
    3. Agora vamos gerar nosso APP, rode no console:
      1
      
      ionic start randomPicCli blank --v2 --ts
    4. Entre no projeto:
      1
      
      cd randomPicCli
    5. Inclua a plataforma android no seu projeto (ou ios usando ios ao invés de android):
      1
      
      ionic platform add android
    6. Agora instale o plugin de acesso a câmera do cordova:
      1
      
      ionic plugin add cordova-plugin-camera
    7. Agora vamos configurar o nosso home.ts para submeter a foto quando o usuário tirar uma novo foto e também para que ele chame nosso service que vai carregar nossa lista com 20 fotos aleatórias. No seu arquivo ‘src/pages/home.ts’ substitua o conteúdo por: (Leia com calma os comentários no código)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      
      import { Component } from '@angular/core';
      import {Camera} from 'ionic-native';
       
      // Carregando nosso service que vai se comunicar com a API
      import {HomeService} from '../../providers/home-service';
       
      @Component({
        selector: 'page-home',
        templateUrl: 'home.html',
        providers: [HomeService]
      })
      export class HomePage {
        // Cricando nossa variavel que vai armazenar as fotos
        public photos: any;
       
        constructor(public homeService: HomeService) {
          // Chama a listagem de fotos quando a página é carregada
          this.loadHome();
        }
       
        // Chama o service para montar a listagem de fotos
        loadHome(){
          console.log('hey');
          this.homeService.load()
          .then(data => {
            console.log(data);
            this.photos = data;
          });
        }
       
        // Chama o service para adicionar uma nova foto
        addPhotoHome(photo){
          console.log('hey 2');
          this.homeService.addPhoto(photo)
          .then(data => {
            this.loadHome();
          });
        }
       
        doRefresh(refresher){
          setTimeout(() => {
            this.loadHome();
            refresher.complete();
          }, 2000);
        }
       
        // Abre o serviço de fotos e depois chama o service para passar a foto que tiramos para a API
        takePicture(){
         Camera.getPicture({
             destinationType: Camera.DestinationType.DATA_URL,
             targetWidth: 1000,
             targetHeight: 1000
         }).then((imageData) => {
             this.addPhotoHome("data:image/jpeg;base64," + imageData);
         }, (err) => {
             console.log(err);
         });
        }
       
      }
    8. Pronto, agora vamos criar a interface que o usuário vai ver quando acessar nosso APP, no arquivo ‘src/pages/home/home.html’ substitua o conteúdo por:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      
      <ion-content class="home">
        <ion-refresher (ionRefresh)="doRefresh($event)">
          <ion-refresher-content
            pullingIcon="arrow-dropdown"
            pullingText="Pull to refresh"
            refreshingSpinner="circles"
            refreshingText="Refreshing...">
          </ion-refresher-content>
        </ion-refresher>
       
        <ion-fab right bottom>
          <button color="dark" (click)="takePicture()" ion-fab><ion-icon name="camera"></ion-icon></button>
        </ion-fab>
       
        <div ion-item *ngFor="let p of photos">
          <ion-card>
            <img src="{{ p['photo']['url'] }}"/>
          </ion-card>
        </div>
       
      </ion-content>
    9. Agora é hora de criamos nosso provider, no console rode:
      1
      
      ionic g provider HomeService
    10. Para permitir que ele se comunique com a nossa API substitua o conteúdo de ‘src/providers/home-services.ts’ pelo código abaixo e depois substitua a frase ‘YOU_API_URL’ pela url para sua API no heroku que criamos anteriormente (ela pode ser encontrada no seu dashboard do heroku na parte de settings do seu APP):
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      
      import { Injectable } from '@angular/core';
      import { Http } from '@angular/http';
      import 'rxjs/add/operator/map';
       
      @Injectable()
      export class HomeService {
        public data: any;
        public api_url: string;
       
        constructor(public http: Http) {
          this.api_url = 'YOUR_API_URL';
        }
       
       
        // Carrega a listagem de Fotos
        load() {
          return new Promise(resolve => {
            this.http.get(this.api_url + '/pics')
              .map(res => res.json())
              .subscribe(data => {
                this.data = data;
                resolve(this.data);
              });
          });
        }
       
        // Adiciona novas fotos
        addPhoto(photo) {
          return new Promise(resolve => {
            this.http.post(this.api_url + '/pics', {'pic': {'photo': photo}})
              .map(res => res.json())
              .subscribe(data => {
                this.data = data.results;
                resolve(this.data);
              });
          });
        }
       
      }
    11. Vamos fazer o build do nosso App para depois podermos testá-lo no device. No console rode:
      1
      
      ionic build
    12. Agora nós já estamos prontos para subir nosso projeto para o Ionic View para testar. O Ionic View é um APP que pode ser instalado no android e no ios e que vai nos ajudar a simular o uso do nosso App.
      a – No seu browser visite https://apps.ionic.io/signup e crie uma conta:
      ionic
      b – Agora vamos subir o APP, rode no console:

      1
      
      ionic upload

      c – Isso vai abrir um prompt perguntando seu user e password que foi criado no site do Ionic View, depois disso seu APP vai ser criado e vai subir.
      d – Agora baixe o APP do Ionic View para seu mobile, http://view.ionic.io/.
      e – Se logue no app, você deve ser capaz de ver o app que você acabou de subir na lista.
      screenshot_2016-12-17-21-17-58-225_com-ionic_-viewapp
      f – Clique nele para visualizar o que acabamos de fazer.

    13. \o/ Pronto, seu app está pronto e conversando com a API.
    14. Agora você pode tirar algumas fotos e ver que elas são adicionadas à linha do tempo. Caso você queria mostrar aos seus amigos (sem efetivamente ter que gerar o APP) basta que eles instalem o ionic view e coloquem o id do seu APP que pode ser encontrado em .io-config.json.
      CONCLUSÃO

      Conseguimos criar nosso APP Ionic 2 + API Rails 5 \o/.
      O Ionic é realmente incrível e faz parecer muito simples a criação de um APP mobile.
      Caso você queira você pode gerar seu APP para a plataforma android e ios e depois subir na play store ou na loja da apple. Se você quiser saber mais sobre o Ionic de uma olhada na documentação oficial clicando aqui: http://ionic.io/2.

      No início de 2017 eu vou lançar um mini curso de ionic 2 + Rails 5 ensinando como clonar um APP como o instagram. Caso você goste desta ideia comenta aí em baixo para eu saber e se cadastre na newsletter do Blog para que você seja avisado quando isso acontecer 🙂

      Como de costume o Código completo da aplicação está no Github, caso você queria clonar o código, clique aqui para ver a parte do Ionic 2 e clique aqui para acessar a parte do Rails 5. Aproveita e me segue lá \o/

      Se você ficou com dúvidas ou tem sugestões de posts para o Blog comenta aí em baixo ou me adiciona no Facebook clicando aqui.

      Muito Obrigado,
      Sua presença aqui é uma honra para mim,
      Leonardo Scorza 🙂

Deixe seu Feedback!

Comentários