2015年8月20日 星期四

Android Web Url Activity 網頁連結啟動app

點選網頁超連結來啟動app
1.AndroidManifest.xml


    

    
        
            
                

                
            
            
                

                
                

                
            
        
    


2.activity_main.xml


    
    


3.MainActivity.java
package tw.android;

import java.util.List;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {
 private TextView textView1;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  textView1 = (TextView) findViewById(R.id.textView1);

  Uri data = getIntent().getData();
  if (data != null) {
   String scheme = data.getScheme(); // "uccu"
   // String host = data.getHost();
   List<String> params = data.getPathSegments();
   String first = params.get(0); // word1
   String second = params.get(1); // word2

   textView1.setText(scheme + ":///" + first + "/" + second);
  }else{
   textView1.setText("請從網頁來");
  }
 }
}
4.web.html
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>

<a href="uccu:///word1/word2/">啟動吧!!APP!!!</a>

</body>
</html> 


參考來源:
http://stackoverflow.com/questions/2958701/launch-custom-android-application-from-android-browser

2015年8月5日 星期三

iOS Swift Multiple PickerView Spinner 多重 關聯 連動 滾輪

2017.06.18 update Android的下拉選項為Spinner
相對應的iOS的為滾輪PickerView

1.首先在Main.storyboard拖拉一個Picker View元件
並點選右方Show the Connections inspector
dataSourcedelegate拉致上方圖片上三個小圖的最左邊小圖關聯
2.將storyboard元件拉至ViewController

3.ViewController繼承UIPickerViewDelegate, UIPickerViewDataSource

4.ViewController.swift

//
//  ThreePickerViewController.swift
//  MultiplePickerViewTest
//
//  Created by Terry Yang on 2017/6/18.
//  Copyright © 2017年 terryyamg. All rights reserved.
//

import UIKit

class ThreePickerViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
    @IBOutlet weak var picker3: UIPickerView!
    
    //第一輪
    var list1  = ["亞洲","歐洲"]
    //第二輪
    var list21 = ["日本","台灣"]
    var list22 = ["英國","德國","義大利"]
    //第三輪
    var list211 = ["東京","沖繩","北海道"]
    var list212 = ["台北","台中","台南","高雄","台東"]
    var list221 = ["倫敦"]
    var list222 = ["柏林"]
    var list223 = ["羅馬"]
    
    //init
    var island : String = "亞洲"
    var country : String = "日本"
    var city : String = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        picker3.delegate = self
        picker3.dataSource = self
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    //幾個滾輪
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 3
    }
    
    //確認各個滾輪有幾筆
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        //component - 第幾個滾輪
        switch(component){
        case 0:
            return list1.count
        case 1:
            return island == "亞洲" ? list21.count : list22.count
        case 2:
            switch country {
            case "日本":
                return list211.count
            case "台灣":
                return list212.count
            case "英國":
                return list221.count
            case "德國":
                return list222.count
            case "義大利":
                return list223.count
            default:
                return 0
            }
        default:
            return 0
        }
    }
    
    //放入內容
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch(component){
        case 0:
            return list1[row]
        case 1:
            //true: 回傳第二輪的亞洲內容 false: 回傳第二輪的歐洲內容
            return island == "亞洲" ? list21[row] : list22[row]
        case 2:
            switch country {
            case "日本":
                return list211[row]
            case "台灣":
                return list212[row]
            case "英國":
                return list221[row]
            case "德國":
                return list222[row]
            case "義大利":
                return list223[row]
            default:
                return nil
            }
        default:
            return nil
        }
    }
    
    //回傳選擇的字串
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        switch component {
        case 0:
            island = list1[row]
            updateCountry(0)
            updateCity(0)
            print("洲: \(island)")
            //選擇第一個滾輪後-重新載入
            pickerView.reloadAllComponents()
            //第二個與第三個滾輪回到第一個項目
            pickerView.selectRow(0, inComponent: 1, animated: true)
            pickerView.selectRow(0, inComponent: 2, animated: true)
        case 1:
            updateCountry(row)
            updateCity(0)
            print("國: \(country)")
            //選擇第二個滾輪後-重新載入
            pickerView.reloadAllComponents()
            //第三個滾輪回到第一個項目
            pickerView.selectRow(0, inComponent: 2, animated: true)

        case 2:
            updateCity(row)
            print("城: \(city)")
        default:
            print("無")
        }
        
    }
    
    func updateCountry(_ row: Int){
        if island == "亞洲" {
            country = list21[row]
        } else {
            country = list22[row]
        }
    }
    
    func updateCity(_ row: Int){
        switch country {
        case "日本":
            city = list211[row]
        case "台灣":
            city = list212[row]
        case "英國":
            city = list221[row]
        case "德國":
            city = list222[row]
        case "義大利":
            city = list223[row]
        default:
            print("無")
        }
        
    }
    
}


檔案下載:
 https://github.com/terryyamg/MultiplePickerViewTest
參考來源:
http://stackoverflow.com/questions/30832489/reload-component-in-ui-picker-view-swift
https://stackoverflow.com/questions/11191062/how-to-reset-uipickerview-to-index0-iphone

2015年8月2日 星期日

iOS Swift 筆記 暫存 SharedPreferences StandardUserDefaults

Android的筆記暫存功能為SharedPreferences
iOS相同的功能為NSUserDefaults.standardUserDefaults()
        //儲存在記事本
        let preferencesSave = NSUserDefaults.standardUserDefaults()
        
        preferencesSave.setValue("張三豐", forKey: "name") //儲存字串
        preferencesSave.setBool(true, forKey: "boy") //儲存布林值
        preferencesSave.setDouble(178.5, forKey: "height") //儲存Double
        preferencesSave.setInteger(99, forKey: "year") //儲存int
        //儲存
        let didSave = preferencesSave.synchronize()


        //讀取記事本
        let preferencesRead = NSUserDefaults.standardUserDefaults()
        
        if preferencesRead.objectForKey("name") == nil {
                //  Doesn't exist
                NSLog("NO name", "...")       
        } else {
                let name = preferencesRead.stringForKey("name") //讀取字串
                let boy = preferencesRead.boolForKey("boy") //讀取布林值
                let height = preferencesRead.doubleForKey("height") //讀取Double
                let year = preferencesRead.integerForKey("year") //讀取int
                NSLog("name:\(name!)", "")
        }

參考連結:
http://stackoverflow.com/questions/19206762/equivalent-to-shared-preferences-in-ios

2015年7月15日 星期三

Android Volley Cache 緩衝 讀取 圖片

先下載資訊,在下滑ListView時,才進行網路讀取圖片。

1.先下載android-support-v4.jarvolley.jar,並在專案下建立libs資料夾,放入libs此資料夾

2.先建立一個list.json檔案,要存成UTF-8格式,並放入圖片url
[{
        "title": "鐵刀",
        "image": "http://terryyamg.3eeweb.com/test/pic/b01.JPG",
        "attack": 480,
        "attributes": "無",
        "material": ["燕雀石x3", "鐵礦石x8","大地的結晶x7", "砥石x12"]
    },
    {
        "title": "鐵刀【禊】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b02.JPG",
        "attack": 528,
        "attributes": "無",
        "material": ["鐵礦石x10", "燕雀石x6", "大地的結晶x10"]
    },
    {
        "title": "鐵刀【神樂】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b03.JPG",
        "attack": 576,
        "attributes": "無",
        "material": ["鐵礦石x15", "燕雀石x12", "大地的結晶x15"]
    },
    {
        "title": "斬破刀",
        "image": "http://terryyamg.3eeweb.com/test/pic/b04.JPG",
        "attack": 624,
        "attributes": "雷:250",
        "material": ["燕雀石x18", "大地的結晶x30", "電氣袋x3"]
    },
    {
        "title": "鬼斬破",
        "image": "http://terryyamg.3eeweb.com/test/pic/b05.JPG",
        "attack": 672,
        "attributes": "雷:380",
        "material": ["輝龍石x5", "燕雀石x20", "電氣袋x5"]
    },
    {
        "title": "鬼神斬破刀",
        "image": "http://terryyamg.3eeweb.com/test/pic/b06.JPG",
        "attack": 768,
        "attributes": "雷:490",
        "material": ["輝龍石x8", "靈鶴石x24", "電龍帶肉肋骨x2"]
    },
    {
        "title": "鬼神斬破刀【極】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b07.JPG",
        "attack": 912,
        "attributes": "雷:620",
        "material": ["白鳩石x14", "電龍霜降肉x4", "祖龍角x1"]
    },
    {
        "title": "鐵刀【冰刃】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b08.JPG",
        "attack": 528,
        "attributes": "冰:100",
        "material": ["鐵礦石x20", "冰結晶x12", "燕雀石x2"]
    },
    {
        "title": "白猿薙",
        "image": "http://terryyamg.3eeweb.com/test/pic/b09.JPG",
        "attack": 576,
        "attributes": "冰:150",
        "material": ["雪獅子的毛x6","鐵礦石x5","冰結晶x8"]
    },
    {
        "title": "白猿薙【中級】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b10.JPG",
        "attack": 672,
        "attributes": "冰:250",
        "material": ["雪獅子王牙x3","雪獅子王的鬍鬚x5","冰結晶x20"]
    },
    {
        "title": "白猿薙【高級】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b11.JPG",
        "attack": 864,
        "attributes": "冰:350",
        "material": ["雪獅子王的利牙x5","雪獅子的剛毛x8","雪獅子王尾x6"]
    },
    {
       "title": "白猿薙【驚嘆】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b12.JPG",
        "attack": 1008,
        "attributes": "冰:560",
        "material": ["牙獸種的重牙x5","草食種的上皮x18","冰冷袋x3"]
    }]


3.AndroidManifest.xml先加入
uses-permission android:name="android.permission.INTERNET"

android:name=".AppController"


    
    

    
    

    
        
            
                
                

                
                
            
        
    


4./res/layout/activity_main.xml 主頁面放入ListView


    
    


5./res/layout/list.xml 建立客製化ListView項目


    
    

    

        
        

        

            
            

            
            
        

        
        
    




先建立AppControllerJsonArrayPostRequestLruBitmapCache三個檔案,此三個檔案不需要進行修改

6.AppController.java
package tw.android;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

import android.app.Application;
import android.text.TextUtils;
import android.util.Log;


public class AppController extends Application {

 public static final String TAG = AppController.class.getSimpleName();

 private RequestQueue mRequestQueue;
 private ImageLoader mImageLoader;

 private static AppController mInstance;

 @Override
 public void onCreate() {
  super.onCreate();
  mInstance = this;
  Log.i("mInstance.this", mInstance+"");
 }

 public static synchronized AppController getInstance() {
  return mInstance;
 }

 public RequestQueue getRequestQueue() {
  if (mRequestQueue == null) {
   mRequestQueue = Volley.newRequestQueue(getApplicationContext());
  }
  return mRequestQueue;
 }

 public ImageLoader getImageLoader() {
  getRequestQueue();
  if (mImageLoader == null) {
   mImageLoader = new ImageLoader(this.mRequestQueue,
     new LruBitmapCache());
  }
  return this.mImageLoader;
 }

 public <T> void addToRequestQueue(Request<T> req, String tag) {
  // set the default tag if tag is empty
  req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
  getRequestQueue().add(req);
 }

 public <T> void addToRequestQueue(Request<T> req) {
  req.setTag(TAG);
  getRequestQueue().add(req);
 }

 public void cancelPendingRequests(Object tag) {
  if (mRequestQueue != null) {
   mRequestQueue.cancelAll(tag);
  }
 }
}
7.JsonArrayPostRequest.java 編碼
package tw.android;

import java.io.UnsupportedEncodingException;

import org.json.JSONArray;
import org.json.JSONException;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;

public class JsonArrayPostRequest extends Request<JSONArray> {

    private Response.Listener<JSONArray> mListener;
    public JsonArrayPostRequest(String url, Response.Listener<JSONArray> listener,
                                Response.ErrorListener errorListener){
        super(Method.GET, url, errorListener);
        mListener = listener;
    }

    @Override
    protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
        try {

         /*utf-8 編碼 否則中文會出現亂碼*/
            String jsonString = new String(response.data, "UTF-8");
            return Response.success(new JSONArray(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e){
            return Response.error(new ParseError(e));
        } catch (JSONException je){
            return Response.error(new ParseError(je));
        }
    }
    @Override
    protected void deliverResponse(JSONArray response) {
        mListener.onResponse(response);
    }
}
8.LruBitmapCache.java 緩衝
package tw.android;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.toolbox.ImageLoader.ImageCache;

/*緩衝*/
public class LruBitmapCache extends LruCache<String, Bitmap> implements
  ImageCache {
 public static int getDefaultLruCacheSize() {
  final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
  final int cacheSize = maxMemory / 8;

  return cacheSize;
 }

 public LruBitmapCache() {
  this(getDefaultLruCacheSize());
 }

 public LruBitmapCache(int sizeInKiloBytes) {
  super(sizeInKiloBytes);
 }

 @Override
 protected int sizeOf(String key, Bitmap value) {
  return value.getRowBytes() * value.getHeight() / 1024;
 }

 public Bitmap getBitmap(String url) {
  return get(url);
 }

 public void putBitmap(String url, Bitmap bitmap) {
  put(url, bitmap);
 }
}



再建立符合自己需要的清單
9.ListItem.java 清單資訊
package tw.android;

import java.util.ArrayList;

public class ListItem {

 private String title, thumbnailUrl,attributes;
 private int attack;
 private ArrayList material;

 public ListItem() {
 }

 public ListItem(String name, String thumbnailUrl, int attack, String attributes,
   ArrayList material) {
  this.title = name;
  this.thumbnailUrl = thumbnailUrl;
  this.attack = attack;
  this.attributes = attributes;
  this.material = material;
 }

 /* 名稱 */
 public String getTitle() {
  return title;
 }

 public void setTitle(String name) {
  this.title = name;
 }

 /* 縮圖 */
 public String getThumbnailUrl() {
  return thumbnailUrl;
 }

 public void setThumbnailUrl(String thumbnailUrl) {
  this.thumbnailUrl = thumbnailUrl;
 }

 /* 攻擊力 */
 public int getAttack() {
  return attack;
 }

 public void setAttack(int attack) {
  this.attack = attack;
 }

 /* 屬性 */
 public String getAttributes() {
  return attributes;
 }

 public void setAttributes(String attributes) {
  this.attributes = attributes;
 }

 /* 材料 */
 public ArrayList getMaterial() {
  return material;
 }

 public void setMaterial(ArrayList material) {
  this.material = material;
 }

}

10.CustomListAdapter.java 建立listview項目清單
package tw.android;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;

public class CustomListAdapter extends BaseAdapter {
 private Activity activity;
 private LayoutInflater inflater;
 private List items;
 ImageLoader imageLoader = AppController.getInstance().getImageLoader();

 public CustomListAdapter(Activity activity, List items) {
  this.activity = activity;
  this.items = items;
 }

 public int getCount() {
  return items.size();
 }

 public Object getItem(int location) {
  return items.get(location);
 }

 public long getItemId(int position) {
  return position;
 }

 public View getView(int position, View convertView, ViewGroup parent) {

  if (inflater == null)
   inflater = (LayoutInflater) activity
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  if (convertView == null)
   convertView = inflater.inflate(R.layout.list, null);

  if (imageLoader == null)
   imageLoader = AppController.getInstance().getImageLoader();
  NetworkImageView thumbNail = (NetworkImageView) convertView
    .findViewById(R.id.thumbnail);
  TextView title = (TextView) convertView.findViewById(R.id.title);
  TextView attack = (TextView) convertView.findViewById(R.id.attack);
  TextView attributes = (TextView) convertView
    .findViewById(R.id.attributes);
  TextView material = (TextView) convertView.findViewById(R.id.material);

  // getting movie data for the row
  ListItem m = items.get(position);

  // 縮圖
  thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);

  // 名稱
  title.setText(m.getTitle());

  // 攻擊力
  attack.setText("攻擊力: " + String.valueOf(m.getAttack()));

  // 屬性
  attributes.setText("屬性: " + m.getAttributes());

  // 材料
  String materialStr = "";
  for (String str : m.getMaterial()) {
   materialStr += str + ", ";
  }
  materialStr = materialStr.length() > 0 ? materialStr.substring(0,
    materialStr.length() - 2) : materialStr;
  material.setText(materialStr);

  return convertView;
 }

}

11.MainActivity.java 主頁面
package tw.android;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;

public class MainActivity extends Activity {// Log tag
 private static final String TAG = MainActivity.class.getSimpleName();

 // json檔案位置
 private static final String url = "http://terryyamg.3eeweb.com/test/list.json";

 private List listItem = new ArrayList();
 private ListView listView;
 private CustomListAdapter adapter;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  listView = (ListView) findViewById(R.id.list);
  adapter = new CustomListAdapter(this, listItem);
  listView.setAdapter(adapter); 
  
  // 取得資料並編碼
  JsonArrayPostRequest itemReq = new JsonArrayPostRequest(url,
    new Response.Listener() {

     public void onResponse(JSONArray response) {

      // 解析json
      for (int i = 0; i < response.length(); i++) {
       try {
        
        //取得回應物件
        JSONObject obj = response.getJSONObject(i);
        //取得對定標題並放入item內
        ListItem item = new ListItem();
        item.setTitle(obj.getString("title"));
        item.setThumbnailUrl(obj.getString("image"));
        item.setAttack(obj.getInt("attack"));
        item.setAttributes(obj.getString("attributes"));
        //多項目處理
        JSONArray materialArry = obj
          .getJSONArray("material");
        ArrayList material = new ArrayList();
        for (int j = 0; j < materialArry.length(); j++) {
         material.add((String) materialArry.get(j));
        }
        item.setMaterial(material);

        // 將所有項目item放入listItem陣列
        listItem.add(item);

       } catch (JSONException e) {
        e.printStackTrace();
       }

      }

      // 更新adapter數據
      adapter.notifyDataSetChanged();
     }
     
     
    }, new Response.ErrorListener() {

     public void onErrorResponse(VolleyError error) {
      VolleyLog.d(TAG, "Error: " + error.getMessage());

     }
    });

  // 使用AppController內的排序
  AppController.getInstance().addToRequestQueue(itemReq);
 }

 @Override
 public void onDestroy() {
  super.onDestroy();
 }



}

1.檔案下載:
https://github.com/terryyamg/CacheImageTest
 2.參考連結:
http://www.androidhive.info/2014/07/android-custom-listview-with-image-and-text-using-volley/
http://dnakreatif.com/programming/android-volley-jsonarray-post-with-params/
http://stackoverflow.com/questions/19267616/why-does-volleys-response-string-use-an-encoding-different-from-that-in-the-res

2015年7月5日 星期日

iOS Swift Time Format Compare 時間 格式 比較

Swift的時間格式化

1.ViewController.swift
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //取得日期
        let date = NSDate()
        println(date) //原始
        var formatter = NSDateFormatter();
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss";
        let date2 = formatter.stringFromDate(date);
        
        println(date2) //格式為yyyy-MM-dd HH:mm:ss
        formatter.dateFormat = "yyyy/MM/dd";
        let date3 = formatter.stringFromDate(date);
        println(date3)//格式為yyyy/MM/dd

        //比較時間
        //現在時間
        let date = NSDate()
        let calendar = NSCalendar.currentCalendar()
        let components = calendar.components([.Month, .Day], fromDate: date) //只取月,日
        let dateNow = String(format: "%02d-%02d", components.month, components.day) //NSDate 轉 字串(格式 日-月)
        //自設時間
        let formatter = NSDateFormatter()
        formatter.dateFormat = "MM-dd" //日期格式
        formatter.timeZone = NSTimeZone(name: "UTC")
        let dateSet = "03-29" //自設時間
        
        let dateA = formatter.dateFromString(dateNow)! //字串 轉 NSDate
        let dateB = formatter.dateFromString(dateSet)! //字串 轉 NSDate
        print("DateA:\(dateA)")
        print("DateB:\(dateB)")
        // 比較
        switch dateA.compare(dateB) {
            case .OrderedAscending     :   print("Date A 比 date B 早")
            case .OrderedDescending    :   print("Date A 比 date B 晚")
            case .OrderedSame          :   print("同日")
        }

    }
}
參考來源:
http://www.brianjcoleman.com/tutorial-nsdate-in-swift/
http://iswift.org/cookbook/compare-2-dates

iOS Swift String Random 字串 亂數 亂碼

swift的隨機亂碼

1.FunctionHelper.swift
class FunctionHelper {

    // 產生亂碼 len-需要亂碼長度
    func randomString(len:Int) -> String {
        let charSet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        var c = Array(charSet)
        var s:String = ""
        for n in (1...len) {
            s.append(c[Int(arc4random()) % c.count])
        }
        return s
    }
    
}

2.ViewController.swift
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let funHelper = FunctionHelper()
        var number = funHelper.randomString(8) //取8位
        println("產生得亂碼:\(number)")
    }
}
參考來源:
https://gist.github.com/szhernovoy/276e69eb90a0de84dd90

2015年7月2日 星期四

iOS CocoaPods libs 安裝套件

1.iOS安裝套件的方法,簡單說就是要用終端機下指令裝一個叫做CocoaPods的軟體,然後用這個軟體在專案下建立一個Podfile檔案,在這個檔案裡面寫入要取得的套件名稱,再進行安裝指令就會自動下載,跟Android Studio的方式比較像,詳細步驟在http://code4app.com/article/cocoapods-install-usage有介紹。

ps:在安裝CocoaPods時要有root權限,開啟設定root請參閱https://support.apple.com/zh-tw/HT204012 "如何啟用 root 使用者" 詳細步驟

2.沒提到的問題,下載套件時可能會出現錯誤
 
[!] Pods written in Swift can only be integrated as frameworks; this feature is still in beta. Add `use_frameworks!` to your Podfile or target to opt into using it.

此時安裝不完全會造成.xcworkspace檔案與Podfile.lock檔案產生不出來

因此要在Podfile加入"use_frameworks!"就可以順利安裝

參考 
http://stackoverflow.com/questions/29091522/error-running-pod-install-with-swift

安裝完成點選出現的.xcworkspace檔案開啟就可以使用了!!讚!!!