protocol Equatable

글 작성중입니다.
글 하나 작성하는데 상당히 오랜 시간이 필요하네요..
곧 마무리 해서 올리겠습니다.

iOS 개발을 하다보면 꽤 많은 프로토콜들이 등장한다.
대부분의 개발자들은 별 생각없이 넘어갈것이라고 생각한다.
그러다가 어느순간에 이건 도대체 뭐지? 라는 의문이 들것이고 이에 대해 알고 싶어질것이라 생각한다.
지금 내가 그렇고, 매번 궁금한게 생길때마다 다시 찾아보는 수고를 덜기 위해 정리해보려고 한다.

equatable| ikwéitəbl | 형용사 | 동일시할 수 있는.

아래 애플링크에 있는 글들을 정리를 좀 해볼께요.
좀 보기 편하게 제 스타일대로 의역을 좀 해놨습니다.
틀린부분이 있다면 알려주세요.

Equatable

Type의 같음을 비교할 수 있다.

개요

Equatable 프로토콜을 따르는 Type들은 equal-to operator (==) 또는 불균형인지를 not-equal-to operator (!=)를 사용하여 비교 할수 있다.

배열와 컬렉션은 Equatable을 만족할때, 쉽게 비교를 수행할수 있다.
예를 들면 다음과 같다.
배열의 요소들이 Equatable을 만족할 때, 제공되는 closure를 사용하여 비교하지 않고, 특별한 값을 포함하고 있는지를 contains(_:) 메소드를 사용하여 체크할수 있다.

let students = ["Kofi", "Abena", "Efua", "Kweku", "Akosua"]

let nameToCheck = "Kofi"
if students.contains(nameToCheck) {
    print("\(nameToCheck) is signed up!")
} else {
    print("No record of \(nameToCheck).")
}
// Prints "Kofi is signed up!"

Equatable Protocol을 따르기

Equatable을 당신이 만든 Type에 추가한다는 것은, Collection에서 특별한 인스턴스를 찾기 위해 convenient APIs를 사용한다는 뜻이다.
Equatable은 base protocol이며, Hashable과 Comparable protocols에도 사용된다.
그리고, Collection의 요소들을 sets과 sorting하여 구성하는 것처럼, custom type을 사용할수 있게 해준다.

Equtable을 만족시며 type를 생성하기 위해서는 다음 두가지를 충족시켜야 한다.

  • Struct일 경우, 모든 properties가 Equatable을 만족 시켜야 한다.
  • Enum일 경우, 모든 value들이 Equatable을 만족 시켜야 한다.
    (value없는 enum은 선언없이 만족된다. 맞는 해석인지 모르겠다. 테스트 필요.)

작성중…

  • 참고 링크
  • https://developer.apple.com/documentation/swift/equatable

[글 작성 중] Firebase 클라우드 메시지 시작하기

Firebase에서 제공하는 푸쉬를 적용해보자.
Pod을 사용할 것이며, 해당 가이드 링크는 참고링크(하단)에 적어놓았다.
https://firebase.google.com/docs/cloud-messaging/ios/client?authuser=0

Firebase에서 프로젝트를 설정하고, 푸쉬를 사용하기 위한 방법입니다.
프로젝트 설정등은 firebase 가이드를 따라 하는 방식을 권장합니다.
따라서 firebase를 XCode에 적용하고, 푸쉬가 오는것까지 확인하는 것을 목표로 작성된 문서입니다.

다음과 같이 Pod을 설정하고 설치한다.
Pod 설정은 가이드 문서를 참고하여 각자의 환경에 맞추어 설정한다.

# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'


target 'SampleRxSwift' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!


  # Pods for SampleRxSwift
  #pod 'RxSwift', '6.0.0-rc.1'
  #pod 'RxCocoa', '6.0.0-rc.1'
  # Add the Firebase pod for Google Analytics
  pod 'Firebase/Analytics'
  # Add the pod for Firebase Cloud Messaging
  pod 'Firebase/Messaging'




  target 'SampleRxSwiftTests' do
    inherit! :search_paths
    # Pods for testing


    # Add the Firebase pod for Google Analytics
    pod 'Firebase/Analytics'
    # Add the pod for Firebase Cloud Messaging
    pod 'Firebase/Messaging'


  end


  target 'SampleRxSwiftUITests' do
    # Pods for testing
    # Add the Firebase pod for Google Analytics
    pod 'Firebase/Analytics'
    # Add the pod for Firebase Cloud Messaging
    pod 'Firebase/Messaging'


  end


end

Pod 설치 및 사용법은 아래 링크를 참고. 또는 가이드 문서를 참고
http://magpiebros.com/wordpress/category/dev-story/ios-개발-이야기/cocoapods/

앱 실행부, AppDelegate 정당한 위치에 아래와 같은 같은 코드를 삽입한다.

class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        print("[AppDelegate] didFinishLaunchingWithOptions")
        FirebaseApp.configure()
        firebaseRegisterForRemoteNotifications(application)


        // 메시지 대리자 설정
        Messaging.messaging().delegate = self
        
        return true
    }

FCM관련 추가

// MARK:- FCM
extension AppDelegate {
    func getFCMToken() {
        print("[AppDelegate] getFCMToken")

        Messaging.messaging().token { token, error in
            if let error = error {
                print("Error fetching FCM registration token: \(error)")
            } else if let token = token {
                print("FCM registration token: \(token)")
                //            self.fcmRegTokenMessage.text  = "Remote FCM registration token: \(token)"
            }
        }
    }
    
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("[AppDelegate] 파이어베이스 토큰: \(fcmToken)")
    }
    
    func firebaseRegisterForRemoteNotifications(_ application: UIApplication) {
        print("[AppDelegate] firebaseRegisterForRemoteNotifications")
        if #available(iOS 10.0, *) {
            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.current().delegate = self
            
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_, _ in })
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
        }
        
        application.registerForRemoteNotifications()
    }
}

APNS 설정

// MARK:- APNS
extension AppDelegate {
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        print("[AppDelegate] 토큰 받음", deviceToken.description)
        Messaging.messaging().apnsToken = deviceToken
    }
    
    
    // 호출되지 않음. iOS 10 미만?
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
        print("[AppDelegate] didReceiveRemoteNotification - 알람 옴")
        // If you are receiving a notification message while your app is in the background,
        // this callback will not be fired till the user taps on the notification launching the application.
        // TODO: Handle data of notification
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        
        // Print message ID.
        //      if let messageID = userInfo[gcmMessageIDKey] {
        //        print("Message ID: \(messageID)")
        //      }
        
        // Print full message.
        print(userInfo)
    }
    
    // 호출되지 않음. iOS 10 미만?
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("[AppDelegate] didReceiveRemoteNotification - fetchCompletionHandler - 알람 옴")
        // If you are receiving a notification message while your app is in the background,
        // this callback will not be fired till the user taps on the notification launching the application.
        // TODO: Handle data of notification
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        
        // Print message ID.
        //      if let messageID = userInfo[gcmMessageIDKey] {
        //        print("Message ID: \(messageID)")
        //      }
        
        // Print full message.
        print(userInfo)
        
        completionHandler(UIBackgroundFetchResult.newData)
    }
}


//
@available(iOS 10, *) 
extension AppDelegate : UNUserNotificationCenterDelegate {
    
    // Receive displayed notifications for iOS 10 devices.
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("[AppDelegate] UNUserNotificationCenterDelegate")

        let userInfo = notification.request.content.userInfo
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        
        // Print message ID.
        //    if let messageID = userInfo[gcmMessageIDKey] {
        //      print("Message ID: \(messageID)")
        //    }
        
        // Print full message.
        print(userInfo)
        
        // Change this to your preferred presentation option
        completionHandler([[.alert, .sound]])
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        print("[AppDelegate] UNUserNotificationCenterDelegate")

        let userInfo = response.notification.request.content.userInfo
        // Print message ID.
        //    if let messageID = userInfo[gcmMessageIDKey] {
        //      print("Message ID: \(messageID)")
        //    }
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        
        // Print full message.
        print(userInfo)
        
        completionHandler()
    }
}

이렇게 코드만 적어놓는것은 역시 도움이 되지 않는 글을 작성해 놓은것 같아 씁쓸한 마음이 남는다. 이것보다 좀더 도움도 되고 발전도 할 수 있는 글을 작성할 수 있도록 고민해보아야 겠다.

  • 참고 링크
  • https://firebase.google.com/docs/cloud-messaging/ios/client?authuser=0