How to learn iOS Programing

1. 蘋果官方教學Swift

https://developer.apple.com/library/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/index.html#//apple_ref/doc/uid/TP40015214-CH2-SW1

2. Stanford CS 193P videos

https://itunes.apple.com/us/course/developing-ios-9-apps-swift/id1104579961 https://itunes.apple.com/us/course/developing-ios-8-apps-swift/id961180099 https://itunes.apple.com/us/course/developing-ios-7-apps-for/id733644550

3. Quora有很多人分享學習的經驗

https://www.quora.com/What-are-the-best-resources-for-learning-iOS-development

Objective-C.Programming.Big.Nerd.Ranch.Guides.2nd.Edition

iOS Programming: The Big Nerd Ranch Guide (4th Edition)

系統開發SOP

SOP

  1. 和客戶確認他要做什麼東西 和客戶一起把user story寫下來

    可以由不懂技術的人員做這一塊 但是知道怎麼去用自然語言描述客戶的需求 轉成一個一個的使用者故事

  2. tecLeader 根據user story 來選擇要使用什麼樣的技術來做

    需要什麼樣的專業人員在協助和人員配置

    例如: 後端使用什麼技術 例如使用Ruby on Rails 4.2.1, Ruby 2.2.2 前端使用什麼技術 例如:RWD,bootstrap,reactjs 什麼樣風格的設計師設計出的風格是客戶所要的

  3. teamwork tool standing by (1) Redmine (2) Git Server (Github or Bitbucket or self server) (3) Staging Server

  4. tecLeader 做系統分析

  5. tecLeader 開始根據人員配置和系統分析摟的結果和案子時程 來進行開票和控管進度流程

[Rails]今天在用購物車時發現一個Session問題

Session換頁之後, 商品沒有紀錄上去

查了之後發現是 From for 在新增商品沒 CSRF的auth code沒有新增

造成對應不到Session

所以每次新增商品時 都會重新開一個Session

所以造成購物車的商品不會累加

另外

由於Session裡面存的是購物車的是一個ruby物件

所以如果用 cookie store 由於 cookie無法儲存物件

所以用cookie會失敗

這個是由在Rails 4.1 之後的更新所做的修正

可參考 1. http://guides.rubyonrails.org/upgrading_ruby_on_rails.html 2. http://blog.plataformatec.com.br/2014/04/3-features-from-rails-4-1-that-im-excited-about/

之前Rails可以將Ruby物件放在Cookie的原因是他使用了 Marshal.dump and Marshal.load 來做物件的serialized (and deserialized)

但是由於這種做法,假如hacker如果拿到你的cookie加密的key就可以從你的cookie 解密出你存在裡面的物件, 所以降低了網站的安全性

因此Rails 4.1的更新, 讓Cookie只能儲存一些簡單的資料, 例如:string, integer, hash, array等 複雜物件就無法儲存

但也不是無法儲存, 只是物件的serialized (and deserialized) 就必須自己做了

網路安全-CSRF-跨站偽裝請求

CSRF 情況:

  1. 瀏覽器如果發送請求時,如果在瀏覽器的cookie紀錄裡面有找到目標Domain的對應的cookie,就會將這個cookie一同送給server做請求

  2. 但是如果使用者在A網站已經認證完,且session尚未timeout

  3. 這個如果使用者在瀏覽B網站時,B網站自動發送一個請求給A網站

  4. A網站會認為是使用者自己發送的

  5. 如此可以達到偽裝使用者在A網站的所有操作

對策:

  1. use GET and POST appropriately

    就是正確的使用Get和Post, 如果是獲取資料的地方就使用GET, 需要更新或是新增的地方就使用POST

  2. a security token in non-GET requests will protect your application from CSRF.

    如果是GET以外的行為例如: POST, 這時就必需使用一個認證碼來驗證次動作

    實作的方法通常就是, 當使用者獲取一個更新操作或是新增頁面的時候, Server會自動產生一個驗證碼(security token)並將它同時 和這個更新操作或是新增頁面同時送到使用者的瀏覽器

    使用者要進行新增或是更新時會POST資料到Server,同時POST的資料裡面會跟隨這個驗證碼(security token)一起送到Server, 所以Server就根據這個驗證碼的正確與否來決定這個POST的行為是正確的還是偽造的

WordPress後台可以直接改改檔案的相關設定?

最近我又使用Wordpress來發佈自己的部落格, 但是發現Wordpress無法直接在後台的管理更改檔案 例如: 更改themes的css或是相關的php檔案

為何會這樣呢? 其實就是個權限問題

但是權限問題要怎麼處理呢?

如果wordpress是運作在Apache上的PHP, 這個情況就是如果Apache是用什麼身份去執行, PHP就會用相同的身份去執行

先看看Apache是用什麼身份執行的, 打上

ps aux | egrep '(apache|httpd)'

如圖: 螢幕快照 2016-04-20 下午10.46.47

可以發現Aapache是使用www-data這個使用者身份在執行的

所以只要你的wordpress的檔案夾可以被www-data身份修改的話, 就可以達到這個需求

要做到這一點只要執行

chown -R [your_user]:www-data wordpress-root

來將wordpress-root的資料夾裡面的檔案更改為 group:www-data

再執行

chmod -R 775 wordpress-root

將他的權限更改為group可以執行修改和讀取的動作

Sinatra 做簡單的ruby Server

ruby寫一個簡單的備份Server

最近有一個需求 就是用ruby寫一個簡單的備份Server

但是如果利用Rails來做的話, 就會覺得簡單的功能,用Rails 反而覺得太複雜了

所以就用Sinatra

Sinatra在背景執行

nohup ruby web.rb >> log/file 2>&1 &

關閉執行的sinatra程序

方式1:
File.open('myapp.pid', 'w') {|f| f.write Process.pid }

shell: kill `cat myapp.pid`

ruby: Process.kill 'TERM', File.read('myapp.pid’)
方式2:
ps aux | grep ruby $ kill <ruby-process-id>

Docker

Docker簡單的來說就是應用程式的虛擬化,有別於VM是作業系統的虛擬化

要玩Docker有幾個重點需要注意的,我將它記錄如下:

1.Container : 就是Docker裡面封裝軟體的容器,也就是一個單位,其實他就是一個將很多其他不重要的元件拿掉之後,所剩下的最基本的Linux作業系統

2.Image : 就是一你的軟體的映像檔,當軟體要執行時,Docker會根據image的資料載入container然後才真正執行

3.Share : Docker讓個人或是公司可以分享他的製作好的image給其他使用者使用,利用Docker-Hub https://hub.docker.com/

4.Corss-Platform 使用Docker,你不必在意使用者使用什麼樣的平台(作業系統),他在每個作業系統(Mac,Linux,Window..)上建構了一個containser虛擬化技術,所以只要封裝成Docker的container,就可以在任何的作業系統上運作你的軟體

5.Run 要執行Docker很簡單只要執行以下指令

$docker run [container name]

6.Docker file : 就是Docker Image的描述檔,告訴Docker說這個軟體要運作在什麼樣的環境,還有要執行什麼指令,簡單的說就是一個軟體運作的食譜

7.Build Image: 當dockerfile裡面的敘述都完成後,就可以根據這個敘述檔產生一個Docker Image,很簡單只要打上以下指令:

$docker build -t docker-whale

8.Docker Image Local: 一般來說Docker在執行時會先在本地端Local尋找是否有要執行的映像檔(Docker Image),如果沒有才會去DockerHub上去下載 如果要知道本地端有什麼映像檔(Docker Image)可以使用,只要打上以下指令

$docker images

9.Push image to Docker Hub 如果要將自己製作好的Image Push到Docker Hub,

第一步. 先去Docker Hub申請帳號
第二步. 再來就是將製作好的Image和自己的Docker Hub關聯起來,指令如下:
$docker tag 7d9495d03763 maryatdocker/docker-whale:latest

7d9495d03763 > 就是利用Image的hash code

可以用 $docker images 指令去查看 maryatdocker/docker-whale:latest

就是Docker Hub上面的repository

第三步. push到Docker Hub
$docker push 

10.Remove form local 要移除local的image只要執行以下指令:

$docker rmi -f 7d9495d03763`

11.Pull from you repository 如果要從Docker Hub將指定的container image 抓取下來,只要執行指令:

$docker pull [yourusername/docker-whale]

iOS View 事件的傳遞 using Swift

一般來說 iOS 裡面最外層的就是 UIViewController這個元件 之後所以有的一個view不管是UILabelView,UIImageView,UITableView…..等 都是附加在這個容器上面

這裏就一個好玩的東西叫做Delegate, 他其實是一個protocol,就是要接收事情的物件實作這個protocol 就可以接收另外一個物件發送的事件

這個東西很好用就在於如果你將一個功能做一個一個物件,但是一這個物件接收到事件後, 必須傳遞到附加這個功能的主物件

這是時候就要用Delegate,在此說明一下使用方法:

例如說:

先宣告一個Delegate功能的protocol

protocol VideoListViewDelegate {
    func tableViewItemClick()
}

我有一個VideoListView的功能物件,當使用者按下TableView的row item時,我必須處理相關的事情 如此當事情發生時呼叫delegate?.tableViewItemClick()

import Foundation 
import UIKit

class VideoListView: UIView, UITableViewDelegate, UITableViewDataSource {

... 

var delegate: VideoListViewDelegate? 

... ...

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        delegate?.tableViewItemClick()


    }
}

之後在ViewController去實作這個protocol,然後再實作這個protocol的方法

import UIKit 

class VideoListHomePageViewController: UIViewController, VideoListViewDelegate { 

    override func viewDidLoad() { 
        super.viewDidLoad()
        var videoView = VideoListView()
        videoView.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableViewItemClick()

      ....處理VideoListView的tableView Item按下時的事情


    }

}

如此就可以在兩個物件當中傳遞事件

Cross Domain AJAX Request And Rails

Because The Browser have the Same-origin policy

Same-origin policy it’s say:

A web browser permits scripts contained in a first web page to access data in a second web pageand only if both web pages have the same origin.

And it’s purpose is:

Prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page’s Document Object Model.

So if We want to use a web ajax to get the data from the cross domain resource How can We do it?

Way1. JSONP

Frontend

$.ajax({ type: 'GET',  
    url: "http://localhost:3000/v1/questions/1/options", 
    dataType: 'jsonp', 
    success: get_options_data_success, 
    error: null 
});

var get_options_data_success = 
function(data) { ...do something you want }

Rails

render json: Question.all, :callback => params[:callback]

If use above, ajax will add ?callback=(Random function name)

such as: ?callback=jQuery21306889237540308386_1436178704662

and the Rails will get the callback params and will resoponse a porcess data /**/
jQuery213014021378150209785_1436178755583( …origin josn data rails will response…)

such as: /**/jQuery213014021378150209785_1436178755583( [{"question_id":1,"id":5,"description":"50+","votes_count":1}])

so Ajax can get the data Rails response and cross domain

Way2. CROSS-ORIGIN RESOURCE SHARING

Browser does not allow cross domain AJAX requests due to security issues.
Cross-domain requests are allowed only if the server specifies same origin security policy.
Read more about Cross-origin resource sharing (CORS)

If you want to enable CORS in Rails , you can add below code to ApplicationController

class ApplicationController < ActionController::Base 
  protect_from_forgery unless: -> { request.format.json? } 
  after_filter :set_cross_domain_access

  def set_cross_domain_access 
    headers['Access-Control-Allow-Origin'] = '*' 
    headers['Access-Control-Allow-Methods'] = 'POST, GET' 
    headers['Access-Control-Allow-Headers'] = '*' 
  end 
end

Reference: http://hayageek.com/cross-domain-ajax-request-jquery/

Chef Vagrant Kitchen多主機自動化部署

這次去參加Rails Pacific,在第一天的Wordshop發現一個好的東西 先介紹一下Vagrant

Vagrant

Vagrant是可以自動建制虛擬機的工具,夠過指令就可以在VisualBox上面自動置虛擬機器,只要指定你要的作業系統版本,下個指令就可以自動安裝

https://www.vagrantup.com/

chef

Chef可以將我們要部署機器的過程轉換成指令的方式(code),讓我們可以自動化的部署和管理我們的機器,讓我們的機器變成可以版本控制,可以測試,和可以重複使用我們先前建置的程式碼

https://downloads.getchef.com/chef-dk/mac

kitchen

可以整合Vagrant和chef http://kitchen.ci/

下面介紹kitchen的使用方法

kitchen init

接下來會產生.kitchen.yml的檔案如下:


driver: name: vagrant

provisioner: name: chef_solo

platforms: – name: ubuntu-14.04 – name: centos-6.4

suites: – name: default run_list: attributes: `\
可以在platforms上面指定我們要安裝的作業系統版本 例如上面我們指定要使用ubuntu-14.04和centos-6.4

先以打上 kitchen list 看看有那些作業系統版本可以安裝 螢幕快照 2014-10-01 下午5.32.13.png

根據我們之前的設定發現有ubuntu和centos可以安裝

接下來執行

kitchen create default-ubuntu-1404
kitchen create default-centos-64`

就會自動下載這兩個作業系統會透過Vagrant自動安裝到VisualBox上面 非常方便吧!

打開VisualBox,發現已經幫我們自動安裝好ubuntu和centos了 螢幕快照 2014-10-01 下午7.02.04.png

要登入ubuntu的話只要執行

kitchen login default-ubuntu-1404

或是

kitchen login ubuntu

就可以登入系統了

kitchen支援

kitchen driver discover

可以列出kitchen所支援的套件

螢幕快照 2014-10-01 下午5.57.53.png

可以看出kitchen還有支援azure,digitalocean,ec2,gce,backspace,openstack和docker

cookbook

接下來要介紹chef’s cookbook,可以把cookbook當作是我們安裝的這檯機器裡面需要什麼樣的原件

在原來的資料夾裡面新增

touch matadata.rb

內容填上 name "app-ok"
version "0.1.0"
再來是建立一個預設的recipe(食譜)

mkdir recipes touch recipes/default.rb

recipe寫法可以參考 http://docs.getchef.com/chef/dsl_recipe.html

chef的recipe可以使用的資源包含:

  1. directory,file,user.group – 創建使用者資料
  2. pakage – system pakage
  3. bash – 用來執行shell script
  4. cron – 更新crontab

更多recipe資源的資料可以參考 http://docs.getchef.com/chef/resources.html

例如:

在 recipes/default.rb 新增 package 'git'
package 'ruby'
然後在 .kitchen.yml 新增我們要跑的run list, 如下: `\


driver: name: vagrant

provisioner: name: chef_solo

platforms: – name: ubuntu-14.04 – name: centos-6.4

suites: – name: default run_list: app-ok::default attributes: `\ 然後執行

kitchen converge

就會自動安裝好git和ruby在ubuntu和centos上面了