Wifi 密碼 - 共享密碼的平台

Wifi 密碼 - 共享密碼的平台

上週利用一些閒暇時間,串接一些服務寫了這個簡單的小工具,
主要為了解決每次到一間新的店家時,都得先找找 Wifi 的資訊:
找店員問、找菜單上有沒有寫、找牆壁有沒有貼⋯⋯
於是乎想找一個地方,把我所知道的 Wifi 帳號及密碼記下來,
儘管只要連線過一次,就不會再詢問了,但至少下次人家問我的時候可以告訴他。

使用流程

打開 Wifi 密碼 - 共享密碼的平台 後,會需要使用 Facebook 做登入的動作,
其主要原因是,裡頭的資訊是由全部使用者共同維護的(共筆的概念),
所以其實會紀錄是哪個使用者新增 Wifi 資訊,但並不會顯示出來。
為了讓使用者承擔一點點微薄的責任,來讓大家都可以比較信任 Wifi 裡頭的資訊可信度,
便加入的登入的系統。

接著我們會看到主畫面:

可以看到目前共筆上,有哪些 Wifi 的資訊:

  • 名稱
  • 地點
  • 狀態
  • 最後更新時間

點擊進去之後,有可能會跳出 AdMob 的獎勵型影片廣告,可以點擊連結看看當初實作的流程。
看完廣告之後才能進到內容頁面,來觀看 Wifi 密碼。

舉報無效

下方有個按鈕可以點選,便可以更改此 Wifi 資訊的狀態為「不可用」,
而目前版本會在前面的列表之中就直接篩選掉,所以並不會看到不可用的內容。
若是有人一直將你家的 Wifi 貼上來,你一直舉報也無法遏止這行為的話,請麻煩告知我⋯⋯
 
 

實作方向 - 登入

臉書的登入參照 Facebook Developer 的相關文件,先建立一個 Facebook 的應用程式;
以及利用 Firebase 的 Auth,裡頭有和 Facebook 結合的文件可以依循著做。

資料庫

這邊是繼續使用 Firebase 上的 Database,它是 NoSQL 的架構,並且可以在 rules 上設計相關規則;
目前我只有使用 .indexOn 和判斷 Auth 是否合法,來決定資料庫的讀寫權限。

使用到的 Framework

  • Firebase
  • RxSwift
  • RxCocoa
  • ReachabilitySwift
  • MapKit

下載連結

Wifi 密碼 - 共享密碼的平台
有興趣的大大,可以下載下來玩玩!
目前裡頭資訊還很少,大多數是我從自己 MacBook 裡頭的 Wifi 資訊貼上去的;
希望藉由大家的共享來充實這方面的資訊。
 
 

APNs

APNs( Apple Push Notification service

相信有在開發 iOS app 的開發者,對於這個詞應該都不會太陌生;
簡單來說,它就是推播的功能。
而推播其實有分成兩種:

  1. Local notification
  2. Remote notification

這兩者的差異就如同名字的一般,前者是本地的通知,後者為遠端的通知。

Local notification

本地推播在 iOS 10 以後,可以參考 UserNotifications 這個 framework。
這邊附上以區域範圍為觸發條件的推播寫法:

而鬧鐘那種概念的,或是遊戲提醒(例如遊戲的愛心已經回滿了,趕快回來玩哦!),
這種以時間作為觸發條件的,則是設定 notification.fireDate,給它一個 Date 便會在那時候觸發。

Remote notification

遠端的推播則是如同聊天軟體常常收到的那種推播(OOO傳送貼圖給您!),
AppDelegate.swift 註冊那些的就不寫在這了~
如果是在公司上班或者和後端合作,寫完註冊推播及回傳 deviceToken 和收到之後要幹嘛的動作,
通常就不會碰到「該如何打推播給 App」的問題,因為 iOS 只需要知道收到該怎辦XD
但總會有需要自己打推播測試、或是開發自己 app  的時候,
這邊就來談談 iOS 開發者該怎麼做!

APNs key

以往我們在產生 APNs key 的時候,是會得到一組有期限的 .p12 檔案,
其中不同的 bundle identifier 會配對到不同的 .p12 檔案;
這是一件蠻麻煩的事情,我們需要管理不同 App 的 APNs key,
上架 20 個有推播功能的 app,就需要維護 20 組 .p12 檔案。

有沒有比較方便的做法?

答案是,有!
如果你是看完這篇文章,才開始接觸推播的話,
那你應該已經找不太到 .p12 要去哪裡產生了!
前陣子是 .p12 和新的 .p8 同時共存在 Apple Developer 的頁面,
而目前畫面則長這個樣子:

在產生 keys 的頁面,我們可以看到只剩下「One key is used for all of your apps.」這種的(.p8),
也就是說,只需要一把 key 便可以打給你所有開發的 app,且它並不會過期!
產生完 key 之後,只有在當下可以下載 .p8 的檔案;
若你當下沒下載,就按完成的話,之後點開則會發現 Download 的按鈕是灰色不可按的,
所以需要好好保存,別把它搞丟了,否則只能夠重新產生一把新的來替換。

接下來?

有了 .p8 檔案之後,我是用 Python 來實作打推播的動作,附上我的檔案

  1. apns_key_id = xxxxxxxxxx(你剛剛下載下來的 .p8 檔名)
  2. apns_key_name = 'AuthKey_xxxxxxxxxx.p8'
  3. team_id = 你的 developer team id
  4. bundle_id = 推播要送到哪個 bundle id

建置 Python 環境

這邊會需要安裝一些 python 的套件:

可以下載 requirements.txt 放到和 .p8 及剛剛 .py 的同個資料夾,並執行
pip install -r requirements.txt
便會將所需要的套件下載安裝;
如果沒有安裝 pip⋯⋯建議可以自行先去 Google 一下XDD

萬事俱備後

把上述的檔案更改好後,和 .p8 放到同一個資料夾,接著開啟 terminal 執行 python。

  1. Test Title:推播的標題
  2. Test Body:推播的內容
  3. device token:要收到推播的裝置 token
  4. False:我最後一個參數是來控制要打給 production server 還是 development server

Python 和 Swift 看起來有點類似,所以應該不難看懂 APNs.py 是在幹嘛~
有問題可以留言給我,或是留在 gist 上!
 

更新:

我將文中內的內容整理至 Github 上,有興趣的人也可以直接去那 clone 下來研究。
 

最後

如果這篇文章對你有一點點幫助的話,可以幫我點個廣告來維持這網站的伺服器月費,
或是在相關的 gist 上給個 Star 鼓勵鼓勵!

淺談 Android 的逆向工程

Android?

是的,這篇正是要寫有關於 Android 的逆向工程,儘管這也很可能是本站唯一一篇XD

起因

看到放在「Hack」的分類上,便可以得知,是因為想要修改遊戲參數而開始涉略⋯⋯
提到 Android 的遊戲開發方式,我們可以簡單地分為兩種類型:

  1. 以 Java 開發
  2. 以 Unity 開發

這篇主要會以 Java 開發的遊戲作為內容分享(因為我想改的遊戲是此類型XD)

先說結論

我目前還沒有修改成功,因為這款遊戲有對 apk 進行混淆的動作⋯⋯

以至於一時之間無法找到我需要的參數來做修改⋯⋯
不過,就先記錄一下如何走到看得到程式碼這一步!

使用到的工具

  1. Apk tool
  2. dex2jar
  3. jd-gui

Apk tool

apk tool 主要負責將 .apk 拆開來,在反編譯之後,可以看到一堆 .smali 及 resource 的相關檔案,
也是負責將修改完的檔案重新包回 apk 的工具。
而由於我沒有修改任何 Code,所以只有解出 .smali 和 resource,看看裡頭有什麼東西和圖片影音檔而已。

dex2jar 和 jd-gui

dex2jar 的功用在於將 .apk 轉成 .jar,配合 jd-gui 打開 .jar 來探究其 source code 內容是什麼。

流程總結

配合上述的三個工具,大概的流程應該是先以 dex2jar 和 jd.gui 來研究程式碼,
並使用 apk tool 拆開 .apk 後修改 .smali,最後重新打包成一個 .apk 安裝到模擬器或手機之中。
因為和 Android 不熟,所以只能進展到這邊就停下腳步⋯⋯
希望有經驗的高手們能夠給予一些協助及引導!

相關參考資料

  1. [Android] 人人都會的 apk 反編譯
  2. [教學] 手機遊戲 apk 檔修改基礎介紹與思路

 

AdMob 獎勵式廣告實作

AdMob

在 Google 的廣告投放服務之中,是以 AdSense 作為主軸,整合所有廣告相關的服務;
而 AdMob 則是其中一個專門針對行動裝置的部分。
所以若 iOS 的開發者想在其應用上放置廣告單元,則需要從 AdMob 著手。

建立廣告單元

首先,需要先到 AdMob 的控制台中,新建一個新的應用程式,
並將 app 的相關資訊填寫完整。

再者,則是建立一個廣告單元,而這篇所要分享的是「獎勵式廣告」的實作。

什麼是獎勵式廣告?

獎勵式廣告的意思就如其名,是一個可以在編輯時設定,
反饋給觀看玩廣告的使用者一些獎勵的一種廣告模式;
如大部分的手機遊戲,觀看影片後可以得到一些鑽石、金幣或者特殊加成等。

設定廣告獎勵

我們可以在這個畫面中,去設定使用者觀看頻率的限制以及獎勵數量。

而在後面程式實作的時候,會講解這邊設定會影響到什麼。

Framework 安裝

你可以透過 CocoaPods 或是直接下載拉進專案之中;
這邊由於我所加入廣告的 App 有整合 Firebase 的相關服務,
而 Firebase 官方並無支援 Carthage,所以在這就一併使用 CocoaPods 來做套件的管理。
因為使用 Firebase,所以只需要在原先的 Podfile 之中加上

並且執行 pod install,即可完成安裝。

AppDelegate.swift

先在上方 import GoogleMobileAds,並需要在 FirebaseApp.configure() 之後,加上 AdMob 的廣告設定:
GADMobileAds.configure(withApplicationID: Your_Ads_ApplicationID)

這樣便可以在一開啟 app 時,和 AdMob 做連結。

獎勵式廣告的流程

獎勵式廣告和一般掛在下方的簽入式廣告不同,它的流程為
一、先和 AdMob 發送獎勵式廣告的 request

二、主動式地去詢問 AdMob 的獎勵式廣告是否就緒;

三、影片完整備看完後,它會以 delegate 的方式告知你剛剛投放的獎勵式廣告,其相關內容設定

大致上的流程就是這樣,接著回到前面所說的設定;
若你有限制使用者觀看的頻率,在觀看完後的限制時間內,會在步驟二的地方得到 false,
所以在流程上需要稍作注意。
而獎勵數量則是會在廣告結束後的 delegate 之中,以 reward 這個物件回傳回來,
它底下會有 amount 這個的參數,便是剛剛所設定的獎勵數量。

開發人員與 UI / UX 設計師之間的合作模式

UI / UX 設計師

在工作了一段時間後,陸續接觸了幾位不同的 UI / UX 設計師,
而每個人做事的方法都有所差異,在這邊簡單地列出幾個想法。

設計師所使用的工具

在 UX 設計師裏頭,有配合過使用 AxureAdobe Xd、或是用 Sketch 直接和 UI 一起出的。
而在 Sketch 的模式下,它裡頭有個詞叫做「symbol」,其意義和 iOS 裡頭的 UIView 相關物件相同。

物件的概念

Sketch 提供了 Symbol 的建立,讓使用者在設計時,能夠把一些重複使用到的元件,做成一個 symbol,
而它會自動定義這個 symbol 哪些值是可以被異動的:

如同上方寫的「中華電信」,便是可被異動的值,但更改這個字串並不會影響整體的外觀。

以 iOS developer 來說

設計師可以了解到,UINavigationBar 的樣貌大概是長這樣,並明白 UIBarButtonItem 能夠控制的外觀欄位有哪些,像是這邊顯示的 Edit 字串。
而設計師也可以自行建構 symbol,來增加重複使用的便利性;這點也如同我們在開發 App 一樣,
會建立一些較容易重複使用到的 UIView 來呈現畫面。
設計師可以更明確地定義物件哪些欄位是會怎麼變動的,像是一個「客製化的按鈕」,
可以先明白它的背景色可能會在其他頁面做換色、或是字體會更改,
這都可以讓開發人員在一開始設計這個按鈕時,都考慮進去來增加彈性。

維持一致性

symbol 的概念,可以維持整個專案的外觀一致性;
也就是說當設計師需要調整剛剛所說的「客製化按鈕」,
想把圓角從 5 pixel 改為 10 pixel,便只需要更改 symbol 即可,
不需要再到各個使用到相同外觀的按鈕,都去一一調整為 10 pixel;
developer 也一樣,只需要更改其類別即可,省去重複定義的時間。
也可降低設計師和開發人員之間的溝通成本,讓彼此能夠更專注地做好自己的工作。

接下來呢?

照著上述的做法,我們已經可以較清楚地和設計師們以一致的用詞溝通元件:
設計師:「在登入畫面的圓形按鈕,背景色要用藍色」
:「等等⋯⋯你說的藍,是什麼藍?」
我們可以理解圓形按鈕是之前所建構的 CircleButton(舉例),但顏色呢?
「就 157AFB 啊~」
這絕對不是一個友善的方式啊⋯⋯
在設計稿中可能會出現的顏色,建議的做法是請設計師都幫它們取個名稱,
並使用一個 structure 來宣告這些顏色。

這樣我們便可以很輕鬆地讓這句話和程式產生連結
「在登入畫面的圓形按鈕,背景色要用藍色」

只需要一開始多花一些心思,定義一下彼此之間的「用詞」,
出份規格表
xxx app -
blue = #157AFB
white = #FFFFFF
要溝通或者調整的時候,就可以省下許多時間了!

Unit test with async functions

iOS Unit test

在寫 Unit test 的時候,有時候會遇到要測試的 function 是 async 的,
但在 Unit test 的 function 之中,它本身就是走單一 thread 來決定測試結果;
若沒有多做其他處理,closure 或是其他 thread 做的事情,便不會反應到結果上。
所以我們需要告知 Unit test,要等待一下我們要測的內容。

建立一個 expectation,並在 closure 裏頭執行一些測試結果判斷,
判斷完後,補上 exp.fulfill() 來告知 waitForExpectations 可以結束等待。
這樣就可以做 async functions 的 Unit test 了~

網域相關設定

昨天,終於在 PChome 購買到 www.Archie.tw
來和大家分享一下這段經歷。
首先,從要建設這個網站的時候,就已經打算購買 Archie.tw 的網域名稱;
一來,讓人方便和我本身聯想在一塊,
二來,是為了解決這個問題:

通常在 Organization Identifier 會建議填上倒裝的網址,如 com.facebook、com.google 之類的,
而我之前私人所寫的 App,多半是隨便打⋯⋯(因為那時候沒有一個依循的地方)。
 
不過,當初在 PChome 要點購買時,發現其實這是有人註冊走的⋯⋯
但還好,它的期限剛好最近會到期(2017-05-12)。
想當然耳,我便是在等到 5 月 12 日時,馬上前往去註冊,深怕自己錯過!
只是上頭的文字依舊是 2017-05-12 過期,並且還是之前那個人的相關資訊,
意思就是說其實網域是還沒被釋放出來的⋯⋯
 
於是便去查詢了相關的資訊,原來網域到期後,會有一段贖回期和釋放期,
原先註冊的人可以在那段時間贖回其網域;
以 .tw 來說,贖回期為 30 天、刪除期為 3 天,
於是乎 2017-05-12 到期的這個網域,其實我得等到 33 天後的 2017-06-14 才能註冊。
 
而就在昨日(2017-06-14)中午時,再更新一次購買的網頁,便發現可以註冊了!
費用為 800 元 / 一年,透過線上刷卡的方式解決了這一個多月來的網域問題!
等付款過後的一、兩個小時內,便可以設定 DNS,將原先 vultr 上的 IP 設定進去,
就可以透過 Archie.tw 連到 vultr 的機器了~
 
另外,vultr 以及 WordPress 都需要做相關的設定,將原先顯示 IP 的地方,
都更改為剛剛獲得的網域名稱,並順道設定 https 的問題。
 

SSL 憑證相關流程

我是到 SSL for free 去申請,並按照其流程取得 .crt 和 .key,
然後使用 vultr 建置 WordPress 時,它會自行在 /etc/nginx/ssl 中建立預設的 server.crt 及 server.key,
個人的做法是將 SSL for free 取得的 .crt 和 .key 重新命名為 server.crt 和 server.key,
並透過 FileZilla 來替換掉原本的檔案,並在 vultr 上重新啟動 server 便解決了 SSL 的憑證問題!

dismiss(animated:completion:)

dismiss(animated:completion:)

這個 method 對於大家而言,應該都不陌生;
UIViewController 可以呼叫這個 method 來關閉,而它所關閉的概念如下:
UINavigationController

  • UIViewController1

  • UIViewController2

  • UIViewController3

不論現在 presentingViewController 是 UIViewController 1、2、或者是 3,
在這三者呼叫 dismiss(animated:completion:) 時,
都會把 UINavigationController 的所有 viewControllers 都 dismiss。
然而一個很常的使用方式是,我們會在 UIViewController 的物件之中,自行呼叫 dismiss:

不過這麼做的話,執行 present(, animated: , completion: ) 的 UIViewController,
就不會知道是在哪個流程或是哪個畫面 dismiss 的。
比較好的做法是,會被 present 的 UIViewController 都能透過 delegate 的方式,
告知原本的 UIViewController 「我按下了什麼按鈕」,
再由前面的 UIViewController 來決定是否 dismiss 或是做其他事。
 
讓整體的流程能夠得到比較好的控制,也讓 UIViewController 彼此之間的關係有個清楚的釐清。

KVOController

KVOController

有關 Observe 的相關做法,在 Swift 上我會選擇使用 RxSwift,那 Objective-C 呢?
在這邊簡單介紹一下 KVOController 的 solution 給 Objective-C 的開發者。
在 NSObject 的子類別下,都會繼承到一個 FBKVOController 的物件,名字為 KVOController;
而這邊要使用的 method 是這個:

  • object 是我們要觀察的物件
  • keyPath 是 object 底下的要觀察的值,它的名稱(key)
  • options 則是填入 NSKeyValueObservingOptions
  • block 再來決定當 object 的 keyPath 那物件有更動時,要做些什麼事

舉個例子

  • observe:self
  • keyPath:NSStringFromSelector(@selector(observeObjectName))

翻成白話文就是 self 去觀察 self.observeObjectName 的 value 變化。

  • block 裡頭的 observer = 觀察的物件,object 則是被觀察的物件

在這個例子之中,observer 剛好和 object 是同一個物件(self),
而我們可以在 //do something 裡頭寫些東西,像是當 observeObjectName 有值更動時,畫面上 UILabel 的 text 會跟著改變之類的。
不過這邊要注意兩點

  1. KVOController 不像 RxCocoa 一樣,有提供 observe UIKit 物件的功能。
  2. readonly 的物件,因為 observe 為監聽 set 的動作,若是直接使用 _observeObjectName = @""; 的方式,則不會被監聽到。
Bitnami