顯示具有 Web API 標籤的文章。 顯示所有文章
顯示具有 Web API 標籤的文章。 顯示所有文章

iOS 開發:APP 如何串接 Web API

關鍵詞:『NSURLSession』、『AFNetworking』、『Objective-C 非同步下載』、『Objective-C 多執行緒』




苹果官方提供的原生网络请求类包括:NSURLConnection 和 NSURLSession。
其中,NSURLConnection 从 iOS9 开始不被官方推荐使用了,而推荐使用从 iOS7 开始出现的NSURLSession。

現在大家都在用 AFNetWorking 作為首選網路請求框架,之前的 ASIHTTPRequest 是基於NSURLConnection 類實現的,早期的 AFNetWorking 也是基於 NSURLConnection 實現,後來iOS9 之後已經放棄了 NSURLConnection,開始使用 iOS 7 之後推出的 NSURLSession,本著追根溯源的原則,首先學習一下 NSURLSession 的實現網路請求,然後再去學習 AFNetWorking。

下面兩個超連結,一篇是簡體字,另一篇是繁體字,
相同的程式碼,但是兩篇的程式碼各有漏掉一些東西... 交互參照吧




GCD 多執行緒的說明與應用:





摘要如下,其餘詳閱參考資料:

GCD (Grand Central Dispatch) 是 Apple 將複雜且不易使用的 Thread 操作方式簡化過的 API,雖然使用起來比起傳統的 thread 會有些限制,但整體來說使用起來輕鬆許多也較安全。 總而言之,GCD為多執行緒的運用,其作用在於可將單一任務拆成多個小任務同時執行,亦或者同時執行多個任務,目的在於縮短執行任務的時間,而最重要的是,要確保不要佔用主執行緒而影響到使用者的體驗。



POST 和 GET:

相同点:都能给服务器传送数据

不同点:

1.给服务器的传输数据的方式
GET:通过网址字符串
POST:通过data

2.传输的数据大小:
GET:网址字符串最多255个
POST:使用 NSData,容量超过 1G

3.安全性
GET:所有传输的数据都显示在网址栏中,相当于明文,直接可见
POST:数据被转成 NSDate (二进制数据)



Google 的 URL 相關參數


https://developers.google.com/custom-search/docs/xml_results?hl=en&csw=1

https://sites.google.com/site/tomihasa/google-language-codes

Google Maps嵌入參數:https://jax-work-archive.blogspot.com/2011/07/google-maps.html



 the tbm URL parameter appears to indicate the filter used. For example:

Applications: tbm=app
Blogs: tbm=blg
Books: tbm=bks
Discussions: tbm=dsc
Images: tbm=isch
News: tbm=nws
Patents: tbm=pts
Places: tbm=plcs
Recipes: tbm=rcp
Shopping: tbm=shop
Video: tbm=vid



gl
Description
Optional. The gl parameter value is a two-letter country code. For WebSearch results, the glparameter boosts search results whose country of origin matches the parameter value. See the Country Codes section for a list of valid values.
Specifying a gl parameter value in WebSearch requests should improve the relevance of results. This is particularly true for international customers and, even more specifically, for customers in English-speaking countries other than the United States.
Examples
This request boosts documents written in the United Kingdom in WebSearch results:
q=pizza&gl=uk


hl
Description
Optional. The hl parameter specifies the interface language (host language) of your user interface. To improve the performance and the quality of your search results, you are strongly encouraged to set this parameter explicitly.
See the Interface Languages section of Internationalizing Queries and Results Presentation for more information and Supported Interface Languages for a list of supported languages.
Examples
This request targets ads for wine in French. (Vin is the French term for wine.)
q=vin&ip=10.10.10.10&ad=w5&hl=fr




Google API

https://www.mile.cloud/zh-hant/introduction-to-google-api/ 介紹的 Google API 主要依從人類基礎的四種能力:聽說讀寫衍伸而成,分別為 Vision API、Video Intelligence API、Translation API、Speech API、Natural Language API。

Vision API 就像是 Google 的照片搜尋功能,主要能夠讓機器辨識物件,如人臉、商標 Logo、圖片中的文字,還可以偵測是否有暴力內容等等。簡單而言,Vision API 會自動辨認照片出現的物品並逐一標記標籤。

Video Intelligence 與 Vision API 類似,但以影片即時標籤為主,深入地把影片片段內容作標籤,其中可自動偵測影片場景轉變,並標記每個場景出現的物品,像是下圖範例中的狐狸與兔子等。

如此一來,在龐大的影片庫裡只需要輸入關鍵字(例如:狗、花、人、跑、飛),不到幾秒鐘就能輕鬆從數部影片中搜尋出和關鍵字吻合的內容,舉例來說,所有影片資料庫中出現「狗」的相關影音都會被標示出來,而且還能知道出現在影片裡的哪個位置。

Translate API 涵蓋一般人最常用的 Google Translation,可即時將句子翻譯成各國語言。另外,也有 Instant Video Translate 功能,只要打開相機的功能,API 可將拍到的文字翻譯成使用者所選取的語言,並以相同的顏色及字體顯示在相同位置,如下圖的牛奶的中英轉換例子。

Speech API 可以想成是 Google 搜尋時常使用的語音轉換文字 (Speech to Text) 功能,使用者只需要說出要輸入的文字,API 就會自動把所說的話即時轉換成文字,省略打字環節。

近期來 Apple Siri、Google Assistant、Amazon Alexa 等語音助手,背後就是借助如 Speech API 的技術。

Natural Language API 能進一步了解語意與情緒。只要輸入一段文字,Natural Language API 便能判斷此段文字的正面、負面或是中性情緒,並給予相對分數,供使用者進一步評估。透過 Natural Language API 自動分析語句功能,便可初步了解使用者的意圖,進而做到許多智慧化的功能。

進階版技術與功能,如 Tensorflow、Google Auto ML、Google Machine Learning Engine,包括 Deep Learning 如何收集各動物間的特徵,從而加強自動辨認的準確性;或是如何使用 ML Engine 定義數據類型去分析等。

上述 Google API 皆為 Google Cloud Platform 所提供的工具,若想動手嘗試便可開啟 Google Cloud Platform API Credentials 申請試用,Google 將提供兩百美金的免費試用額度。

Access-Control-Allow-Origin 跨域訪問相關議題

理解 Ajax 與跨來源請求:https://blog.techbridge.cc/2017/05/20/api-ajax-cors-and-jsonp/

原來 CORS 沒有我想像中的簡單:https://blog.techbridge.cc/2018/08/18/cors-issue/

HTML2Canvas:用Javascript來做螢幕截圖,仍然會受到 跨域訪問 限制
http://www.ladesign.tw/paper/info/jquery_html2canvas_download



ajax 设置Access-Control-Allow-Origin实现跨域访问
https://blog.csdn.net/fdipzone/article/details/46390573

摘要:
ajax跨域访问是一个老问题了,解决方法很多,比较常用的是JSONP方法,JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全。

如果跨域使用POST方式,可以使用创建一个隐藏的iframe来实现,与ajax上传图片原理一样,但这样会比较麻烦。

ps. 如何創建一個隱藏的 iframe:http://21st.each1.net/2018/07/csrf-cross-site-request-forgery.html

因此,通过设置Access-Control-Allow-Origin来实现跨域访问比较简单。

例如:客户端的域名是www.client.com,而请求的域名是www.server.com

如果直接使用ajax访问,会有错误

在被请求的Response header中加入

// 指定允许其他域名访问
header('Access-Control-Allow-Origin:*');
// 响应类型
header('Access-Control-Allow-Methods:POST');
// 响应头设置
header('Access-Control-Allow-Headers:x-requested-with,content-type');
就可以实现ajax POST跨域访问了。

實現的代碼摘要如下:

client.html 路径:http://www.client.com/client.html

<script type="text/javascript">
    $.post("http://www.server.com/server.php",{name:"fdipzone",gender:"male"})
      .done(function(data){
        document.getElementById("show").innerHTML = data.name + ' ' + data.gender;
      });
</script>

server.php 路径:http://www.server.com/server.php

<?php
$ret = array(
    'name' => isset($_POST['name'])? $_POST['name'] : '',
    'gender' => isset($_POST['gender'])? $_POST['gender'] : ''
);

header('content-type:application:json;charset=utf8');
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:POST');
header('Access-Control-Allow-Headers:x-requested-with,content-type');

echo json_encode($ret);
?>

Access-Control-Allow-Origin:* 表示允许任何域名跨域访问
如果需要指定某域名才允许跨域访问,只需把Access-Control-Allow-Origin:*改为Access-Control-Allow-Origin:允许的域名

例如:header('Access-Control-Allow-Origin:http://www.client.com');

如果需要设置多个域名允许访问,这里需要用php处理一下

例如允许 www.client.com 与 www.client2.com 可以跨域访问

server.php 修改为

<?php
$ret = array(
    'name' => isset($_POST['name'])? $_POST['name'] : '',
    'gender' => isset($_POST['gender'])? $_POST['gender'] : ''
);

header('content-type:application:json;charset=utf8');

$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';

$allow_origin = array(
    'http://www.client.com',
    'http://www.client2.com'
);

if(in_array($origin, $allow_origin)){
    header('Access-Control-Allow-Origin:'.$origin);
    header('Access-Control-Allow-Methods:POST');
    header('Access-Control-Allow-Headers:x-requested-with,content-type');
}

echo json_encode($ret);
?>




Web API

2020年,預計全球有30萬個API生成;《財富》雜誌的100大公司,也都將要開放API;API驅動的行動應用,市場規模至2015年將增長到250億美元。大數據與雲端時代,API已成為串聯新應用的關鍵,將舊有服務加值,把商業模式更新,大企業、新創者,你不能不認識它。

何謂 Omni-Channel Retail 全通路零售 (全渠道零售):https://21st.each1.net/2018/07/omni-channel-retail.html


已經進入SaaS / PaaS / IaaS 時代已久,還在用舊時代想法規劃網站嗎?

「 以Google為例,透過 GoogleMapAPI,第三方開發者可以輕易的使用 Google Map 所提供的套件,串接Google的地圖資料,並鑲嵌在自己的網路。Twitter 利用 WebAPI 分享他們龐大會員的資訊。Amazon 則提供了一個代管主機的應用介面;微軟更是把傳統的Office變成了雲端服務的Office365 」

從上述案例來看,以雲端服務為導向的商業模式,正在這幾年蓬勃發展。但並非是透過網路就是所謂的雲端服務,從雲端機房到WebAPI,其中的學問可是大不相同,雲端服務的類型如下:


傳統方式:

過去的網路公司,主要都是以傳統方式建置產品和服務,不管是從Server硬體、網路、作業系統、機房等等,都由公司一手包辦。而為因應產品的類型,是否用多少頻寬的網路、作業系統、是否使用虛擬主機VM等...都會影響到產品的效能,這樣的建置方式不僅需要對每個技術環節,都有相當程度的了解和考究,投入的時間和人力成本也更是一大考量。

IaaS(Infrastructure as a Service),基礎建設即服務 :

將網路建置及server硬體採買、是否虛擬化過程交給廠商管理,而公司本身只要針對硬體設施以外的項目如作業系統、硬體上所需執行的服務及應用程式即可,或是我們可以解釋成僅和外部廠商租賃雲端機房、伺服器、網路環境等等,而不用像過去需要在公司內部自行建置機房,而大部分提供雲端機房的環境亦提供恆溫、24小時監控外、機房本身又具備高規格的防震等級,可以有效負擔掉企業內部機房的維運成本。

PaaS(Platform as a Service), 平台即服務:

除IaaS的項目之外,更把作業系統、開發程式環境都交給廠商管理,這樣公司只要專注在資料處理及服務(應用程式)的開發項目,就像Microsoft Azure所提供的Paas服務,像IaaS一樣提供包括基礎架構服務器,存儲和網路,而且還包括開發環境、開發工具,商業智能(BI)服務,數據庫管理系統等。以微軟Azure而言,PaaS旨在支援完整的Web應用程序生命週期:構建,測試,部署,管理和更新,並於Paas項目上提供更完善的維護及管理。


SaaS(Software as a Service),軟體即服務:

透過提供已經產品化的軟體服務是近年來營利的一大趨勢,使用者不再需要負擔自己的開發成本,只需要向廠商訂購該服務,就可以替企業省下大筆的資金。舉Google為例,它提供免費的電子郵件、日曆等服務給大眾使用外,還針對企業推出服務層級協定(SLA)較高的付費網路郵件服務,企業不需要另外採購應用電子郵件的軟體和硬體設備,只要訂購Google的Gmail服務,就能取代自建的電子郵件系統。

像Google Analysis & Adobe Sitecatalyst,也屬於SaaS的一種,提供以監控平台作為服務,透過Web方式登入並提供資料挖掘和商業數據分析。像是社群網站Facebook也可以算是SaaS的一種囉! (常見的SaaS例如 Gmail郵件、Zendesk線上客服、Codepen 線上程式編輯器)

補充說明:
這邊的SaaS與在網站開發CSS style 進階技術的Sass唸起來是一模一樣。
如果這口語上聽到這個詞必須要依照內容情境來推論對方在講什麼,商業上多半是講SaaS,網站開發規格則比較可能是Sass。

「從SaaS談到API,進入雲端產品的新世代」

以雲端產品為代表的新時代即將到來,大型企業在軟體上的開發、維護與消費上都出現了重大轉變,更代表著程式設計師在未來可以賦予產品上更高的服務價值,AWS,Facebook,Google,Twitter和數千家其他網路公司,都透過提供WebAPI的方式大打經濟戰,而服務與服務之間的互動,也從過去SaaS的接口,轉移到WebAPI身上,那API是什麼呢?

API全名叫做應用程式介面(英語:Application Programming Interface,簡稱:API),主要的概念就是把各家或是各種軟體系統的「服務」,做成一種可以「互相溝通」的一種介面,透過服務呼叫、串接的方式來進行產品與產品之間的合作與溝通,重點就在「服務」與「互相溝通」這兩個關鍵字上。

補充說明:
其實很多網路公司在內部討論的時候不用 WebAPI,而直接使用API來稱呼網路服務接口,但API 的全名 Application program interface 只是代表應用程式的使用介面/接口,遠在網際網路還不純熟的時代就已經存在,無論是C語言系列的header檔,到製作成動態函式庫,都可以使用這個名稱。因此本文以WebAPI來表達一般網站所提供的外部程式接口。

我們舉例來說吧

當我們要去大賣場買鞋子的時候,找到了心儀的鞋子卻找不到適合的尺寸,這時該怎麼作呢?

當然我們可以翻箱倒櫃的在賣場中去尋尋覓覓,但這通常不是一般人會做出的直覺選擇吧,其中花費的時間與體力都是無形中的一種成本,還未必可以找到想要的東西,所以我們通常都會選擇「請店員來協助我們」做為我們找鞋子的方式吧!

當你在呼喚了店員請他們協助時,無形中就是對「服務」的一種呼叫,而呼叫店員的這動作就是「API」,他提供的是一種服務,透過呼叫的方式來和另外一支服務「協助找尺寸」去做串接。

1.想找到想要的鞋子尺寸:服務的目的

2.呼叫店員請店員協助:與「協助找尺寸」 的服務進行呼叫與溝通

3.跟店員表示自己要的鞋子和尺寸:提出呼叫服務的需求與規格-我要什麼東西

4.拿到鞋子:完成你需要的服務

當然,主要透過Web作為介面的,就是WebAPI囉!


舉一個實際上在網站上的例子吧!

像 Uber 中使用 GoogleAPI 來當作地圖和導航的介面,不僅可以減少 Uber 團隊開發自己圖台及精算最佳路徑的成本,更可以把團隊的精力投注在優化產品服務及使用者體驗的項目上,無疑是對產品的一大助力。

而在一般我們看到的APP裡面,所有的動態資訊也都是透過WebAPI和後台DB去進行服務串接的,例如:連鎖咖啡店的會員APP,當你希望使用「檢視優惠」的服務時,就會透過WebAPI的方式,把APP後台上架的這些優惠活動、折扣等等,進行串接,而優惠活動更是動態且持續更新的,總不能每次都版本更新之後才把活動進行上架吧,光是 iOS 上架的那些繁瑣程序就會讓你心力交瘁了。

透過上述的例子,我們可以發現,一項集所有服務於一身的大型產品,不僅本身維運上的成本難以想象,其中對於所提供服務的彈性上更是較難突破,不如把服務切分成各種的WebAPI來做串接,不僅可以分散維護風險外,還可以透過「服務」來創造商機,例如以產品做接口來說,「電商網站」和「社群網站」就沒有達到有效的連想,但如果把電商網站的「搜索商品」、「推薦商品」做成一隻對外接口的廣告服務WebAPI,和Facebook的廣告WebAPI做對接,這樣不僅可以在瀏覽動態時做置入性行銷,透過社群間的串接後面產生的經濟效益,更是無法預期。

而一項項服務維護的費用,肯定比維護產品來的少許多,也許在產品草創的初期,有效的運用核心資源,把一些不必要的工作外包給這些雲端服務,並把軟體產品的功能「外包」給WebAPI,讓團隊專注在更快地創建和發布新的業務模式,來保持公司的業務彈性與競爭力,也許這也是快速開發的重要法則。

RESTful Web API

在HTTP協定中,定義了多種不同的method做為服務的請求方法,近年來由於行動裝置的普及化,越來越多的產品及網站,都提供了WebAPI服務,因此身為程式設計師的我們,在設計API為主的Web服務時,對於HTTP請求方式的認知,更是相當重要。

最常見的method,五種如下:
GET
POST
PUT
PATCH
DELETE

所有的字看起來既熟悉又陌生,因為在Http的協定下,每一種呼叫方式都會有一種他專屬的特殊定義,對於寫過網站的人來說,GET和POST絕對毫不陌生。

當Web service使用Web API進行介面介接時,每一串我們設計的URL,就會是一個專屬的服務『窗口』。

舉例來說,像是讀取及上傳的動作,就屬於完全不同的業務,所以當然也會用不同的呼叫方式來設計。

簡單說,不同的Method就是對同一件事情做不同的操作。

以搭買鞋子為例子做衍生吧!

GET:取得型錄,了解想要找的鞋子、型號、規格等。
POST/PUT:呼叫店員協助幫忙找鞋子,並買到想要的鞋子。
PATCH:結帳後向店員更換尺寸或加價購買其他配件如鞋帶、襪子等。
DELETE:跟店員說我不要了。

用生活化的例子講解完後,改以程式的角度來說明

GET:取得(想要的服務)的資料或是狀態。(safe & idempotent)
POST:新增一項資料。
PUT:利用更新的方式於"指定位置"新增一項資料。 (idempotent)
PATCH:在現有的資料欄位中,增加或部分更新一筆新的資料。
DELETE:指定資料刪除。 (idempotent)

這裡突然出現了兩個名詞 safe & idempotent,這兩個是HTTP狀態描述的專有名詞。

「safe」是指該操作不會改變原本的資源狀態,並且同樣的結果是可以被快取(Cache)的。

例如: 查看訂單是不會改變訂單本身紀錄。

「idempotent」是指該操作不管做1遍、2遍或多遍,都會得到同樣的資源狀態結果。

例如: 同一筆資料被DELETE了2次,雖然都是一樣的結果,但第二次發送會因為資料已經被刪除而失敗喔!

GET / POST 我們用得很多所以沒什麼問題,DELETE與字意上相符所以不難理解。

其中讓人困擾的是 PATCH & PUT,要解釋它們必須參考定義 (RFC 5789)。

https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5

依照 RFC 5789,
POST/PUT 都可以用來新增,
PATCH/PUT 都可以用來修改,
但其中的差別在哪裡呢?

POST的定義上屬於將原先沒有的資料去做一筆新增的動作,
PATCH就是一般常見的修改,
所以真的有問題的其實是PUT。

PUT在定義上(idempotent)無論做多少次,回傳結果都會一樣。

以POST來說,我要一雙鞋,我就會得到一雙鞋;
但是如果再用POST發一次我要一雙鞋,會出現兩種可能;
一種是我"再"得到一雙鞋,而且這雙鞋跟上一雙是不一樣的(以資料庫來說,就是ID不一樣);
或是我只能有一雙鞋,所以他會跟我說"錯誤"!! 我已經得到一雙鞋了。

但以PUT來說,無論我發多少次,他都會回我,我有一雙鞋,而我並不會變成兩雙鞋;
當然如果商店沒鞋,則變成我沒有鞋。

這點在很多程式框架裡面都有不完全正確,像 Ruby On Rails 的 PUT 與 PATCH 看起來是一件事(當然你可以自己修正)。

定義是絕對的,但應用是彈性的,所以你可以說這些框架做的與 RFC5789 不一樣,但或許這樣比較好用。
這就看個人取捨,當然,考試的時候通常需要寫 RFC5789 的定義。

另外,PUT 除新增外亦可以做更新請求,假設使用 PUT 做更新,不管是既有的資料或是覆蓋原先的資料,都會利用覆蓋的方式去更新,但假如你的資料裡面有圖檔的話,每 PUT 一次,圖檔就必須要再重新上傳一次,是相當耗費資源的。

而 PATCH 則可以針對已經存在的資料欄位去做部分更新,例如:我們在更新履歷表時,使用PATCH 就可以僅更新裡面的資料,如年齡、工作經歷等欄位,而 PUT 就像是把整份改好的履歷表重新上傳。

PATCH 也可以更新本身一開始 PUT 資料內沒有的欄位,故 PATCH 是非屬於 idempotent 的操作。

所以如果我們以電腦操作檔案來譬喻,建立一個新檔案是POST,修改檔案是PATCH,從別的地方複製檔案貼上就是PUT (無論你貼上幾次都是同一個檔案)。

當然Web API沒有一定要照著上面的定義敘述建立,但如果你符合的話,你可以將它稱作Restful API
(Rest化 = Restful,如果常常不知道講述的時候該用 Rest 或是 Restful 可以這樣去記,被轉化成 Rest架構 的 Web API = Restful API)

REST全名 Resource Representational State Transfer ,可譯為具象狀態傳輸,若是把各個單字拆開來解釋的話即如下:

Resource:資源。
Representational:表現形式,如 JSON,XML...
State Transfer:狀態變化。即上述講到的可利用HTTP動詞們來做呼叫。

簡單的說,就是一個單從發出的HTTP要求裡面所包含的資訊,就可以直接預期這要求會收到怎樣類型的資料。再更白話一點,就是人眼看得懂。

REST指的是網路中Client端和Server端的一種呼叫服務形式,透過既定的規則,滿足約束條件和原則的應用程式設計,對資源的操作包括獲取、創建、修改和刪除資源,這些操作就是依照我們前面所提到的HTTP Method: GET、POST、PUT、PATCH和DELETE。這正好會對應到資料庫基本操作CRUD。

CRUD 為 Create(新增)、Read(讀取)、Update(更新)與Delete(刪除)的縮寫。

接著我們繼續舉例來說,如果我們正在寫一隻商品的WebAPI,讓工程師隨便寫可能會有以下方式來作interface:

獲得商品資料 GET   /getAllItems
獲得商品資料 GET   /getItem/11
新增商品資料 POST /createItem
更新商品資料 POST  /updateItem/
刪除商品資料 POST  /deleteItem/

若是以使用 RESTful API 開發的話:

獲取商品資料 /GET     /items
獲取商品資料 /GET     /items/1
新增商品資料 /POST   /items
更新商品資料 /PATCH /items/1
刪除商品資料 /DELETE /items/1

PUT 則是比較特別一點,其實它並不直接對應CRUD裡面的任何一項。

在這樣的風格中最有名的,應該就是 Ruby on Rails了吧!

透過 HTTP 為基礎來設計 RESTful API,不僅可行,更可以更簡單扼要呢!

最後要提醒大家,我們沒辦法直接在 HTML的<form>裡面使用GET 與 POST以外的Method,因為瀏覽器都還不支援,如果想要發送 Restful request 一般都要後台程式的支援,而且必須要在<form>裡面藏一個<input name="_method" value="你的HTTP Request方法"> 才有辦法送出去。


資料來源:
https://progressbar.tw/posts/51
https://progressbar.tw/posts/53




程式語言編年史

程式語言編年史原文 下面這張圖片描繪了整個程式語言的歷史。包括各種程式語言的發明人、程式語言的特點和適用領域、被什麼網站或公司使用等 (檢視 完整高清圖 )。 之所以會有那麼多不同的程式語言是因為設計程式語言的初衷不同、對語言學習曲線的追求不同、不同程式之間的執行成本差異...