每一台餐車,都有背後的故事...
這是一款專屬給餐車與吃貨的小天地
在首頁可以查看所有營業中的餐車並找尋他們的位置
- Google Map 自定義的 GMSMarker 顯示營業中的餐車位置
- 設計自定義的
UICollectionViewFlowLayout
呈現卡片式的餐車資訊,並且在切換卡片時跳轉至該餐車位置 - 引用
Core Location
&Contacts
的postalAddress
轉換經緯度為精確的地址
let address = location.subAdministrativeArea + location.city + location.street
- 所有餐車列表依據營業與否的順序排列,並點擊後可以進入餐車的詳情頁面
- 用戶可增添喜愛餐車,並同時訂閱(toTopic)該餐車的推播通知; 取消喜愛餐車選項時同步刪除訂閱推播。
func subscribeTopic(toTopic topic: String, completion: (() -> Void)?) {
Messaging.messaging().subscribe(toTopic: topic) { (error) in
guard let error = error else {
completion?()
return
}
}
}
func unSubscribeTopic(fromTopic topic: String, completion: (() -> Void)?) {
Messaging.messaging().unsubscribe(fromTopic: topic) { (error) in
guard let error = error else {
completion?()
return
}
}
}
- 使用 HandleOpenURL 開啟 URL 的方式,讓用戶可以開啟 GoogleMap 的 App,導航到該餐車的位置。
- 實作 Firebase Snapshot Listener 即時的顯示用戶發送的訊息,增添使用者間的互動
- 設計 Auto Layout 顯示聊天室的 bubble 對話框,並依據不同的對象繼承
ChatMessageCell
後更改顯示的樣式 - 針對用戶需求加入
ChatMessageCellDelegate
實作長按頭像的封鎖功能
透過QR Code 的方式蒐集餐車發送的徽章
- 開啟 QR Code 的掃瞄器 : AVFoundatin 的
AVCaptureDevice
- 利用 AVMetadataObject 將 QRCode 收到的訊息轉換成字串並存入 User 內 ->
metadataObj.stringValue
- 引用
CASpringAnimation
達成收到徽章時的動畫效果
使用 Sign In With Apple & Firebase Authorization 作為用戶登入&註冊的方式,並使用 KeyChain 儲存用戶的登入狀態。
- 提供修改照片的功能,設計 OpenChoseCameraManager 開啟選擇相簿內的照片,並針對上傳的照片調整大小。
- 探索餐車與喜愛餐車的 UI,使用巢狀 CollectionView 搭配 Delegate, Singleton 的設計模式完成。
- 對喜愛餐車開店的推播提醒通知,並處理點擊通知後跳轉至首頁該餐車的資訊。
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
//添加點擊通知後要做的事情
}
- 使用 Google Map 選取開店時的位置,同時在開店時使用
URLSession
做發送開店通知的處理
FirebaseNotificationManager.share.sendPushNotification(
toTopic: currentTruck.id,
title: NotificationContent.title + " [\(currentTruck.name)] " + NotificationContent.open,
body: NotificationContent.body,
latitude: lat,
longitude: long)
- 建立 QR Code 的徽章,並在限時內關閉 QR Code
func generateQRCode(from string: String) -> UIImage? {
let data = string.data(using: String.Encoding.ascii)
if let filter = CIFilter(name: "CIQRCodeGenerator") {
filter.setValue(data, forKey: "inputMessage")
let transform = CGAffineTransform(scaleX: 5, y: 5)
if let output = filter.outputImage?.transformed(by: transform) {
return UIImage(ciImage: output)
}
}
return nil
}
- GoogleMaps - 顯示餐車位置及用戶位置
- Firebase
- Auth - 驗證用戶註冊與登入資訊,並針對錯誤進行處理
- Storage - 儲存用戶上傳後的照片,並顯示於畫面
- Messaging - 訊息推播工具,用來發送老闆開店資訊
- Kingfisher - 善用快取的方式處理網路圖片並呈現在 App
- SwiftLint - 檢查 codeing Style 的工具
- Crashlytics - 掌握 App 的 Crash報告
- IQKeyboardManager - 解決鍵盤彈起時遮住輸入框的工具
- lottie-ios - 呈現動畫效果
- JGProgressHUD - 顯示狀態的提示窗
- Xcode 11
- iOS 13 SDK