Skip to content

Instantly share code, notes, and snippets.

@noff
Last active July 27, 2020 06:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noff/a2b98f46fe79351277f81310d4299eba to your computer and use it in GitHub Desktop.
Save noff/a2b98f46fe79351277f81310d4299eba to your computer and use it in GitHub Desktop.
Marketing SDK for iOS
//
// Пример вызова методов SDK при запуске приложения.
//
import UIKit
import PersonalizationSDK
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var sdk: PersonalizationSDK!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
sdk = createPersonalizationSDK(shopId: "somekey", userId: "123", userEmail: "email@fake.com", userPhone: "+77777777777", userLoyaltyId: "A3384BBA4")
print("1. Testing tracking")
sdk.track(event: .productView(id: "123")) { result in
print(" Product view callback")
}
sdk.track(event: .categoryView(id: "123")) { result in
print(" Category view callback")
}
sdk.track(event: .productAddedToFavorities(id: "123")) { result in
print(" Product added to favorities callback")
}
sdk.track(event: .productRemovedToFavorities(id: "123")) { result in
print(" Product removed from favorities callback")
}
sdk.track(event: .productAddedToCart(id: "123")) { result in
print(" Product added to cart callback")
}
sdk.track(event: .productRemovedFromCart(id: "123")) { result in
print(" Product removed from cart callback")
}
sdk.track(event: .syncronizeCart(ids: ["1", "2"])) { result in
print(" Cart syncronized callback")
}
sdk.track(event: .orderCreated(orderId: "123", totalValue: 33.3, products: [(id: "1", amount: 3), (id: "2", amount: 1)])) { result in
print(" Order created callback")
}
print("===")
print("2. Testing product recommendations")
sdk.recommend(blockId: "block1", currentProductId: "1") { result in
print(" Recommendations requested callback")
}
print("===")
print("3. Testing search")
sdk.search(query: "iphone", searchType: "instant") { result in
print(" Instant search callback")
}
sdk.search(query: "iphone", searchType: "full") { result in
print(" Full search callback")
}
print("===")
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
//
// PersonalizationSDK.swift
// PersonalizationSDK
// Описание интерфейса
import Foundation
public enum Event {
case productView (id: String)
case categoryView (id: String)
case productAddedToFavorities(id: String)
case productRemovedToFavorities(id: String)
case productAddedToCart (id: String)
case productRemovedFromCart (id: String)
case syncronizeCart (ids: [String])
case orderCreated(orderId: String, totalValue: Double, products: [(id: String, amount: Int)])
}
public enum SDKError: Error {
case incorrectAPIKey
case initializationFailed
}
public struct RecommenderResponse {
// TODO
var recommended: String
}
public struct SearchResponse {
// TODO
}
public protocol PersonalizationSDK {
func setProfileData(userEmail: String?, userPhone: String?, userLoyaltyId: String?, completion: @escaping (Result<Void, SDKError>) -> Void)
func track(event: Event, completion: @escaping (Result<Void, SDKError>) -> Void)
func recommend(blockId: String, currentProductId: String?, completion: @escaping (Result<RecommenderResponse, SDKError>) -> Void)
func search(query: String, searchType: String, completion: @escaping(Result<SearchResponse, SDKError>) -> Void)
}
public func createPersonalizationSDK(shopId: String, userId: String? = nil, userEmail: String? = nil, userPhone: String? = nil, userLoyaltyId: String? = nil) -> PersonalizationSDK {
return SimplePersonaizationSDK(shopId: shopId, userId: userId, userEmail: userEmail, userPhone: userPhone, userLoyaltyId: userLoyaltyId)
}
//
// SimplePersonalizationSDK.swift
//
// Пример реализации SDK с помощью интерфейса
//
import Foundation
class SimplePersonaizationSDK: PersonalizationSDK {
var shopId: String
var userSession: String
var userSeance: String
var userId: String?
var userEmail: String?
var userPhone: String?
var userLoyaltyId: String?
var urlSession: URLSession
var apiHost = "api.somedomain.com/"
init(shopId: String, userId: String? = nil, userEmail: String? = nil, userPhone: String? = nil, userLoyaltyId: String? = nil) {
self.shopId = shopId
// Generate seance
self.userSeance = UUID().uuidString
// Trying to fetch user session (permanent user ID)
self.userSession = UserDefaults.standard.string(forKey: "personalization_ssid") ?? ""
self.urlSession = URLSession.shared
sendInitRequest { initResult in
switch initResult {
case .success:
print(initResult)
self.sendUserInitRequest { userInitResult in
// TODO: Save init parameters
}
case .failure:
// TODO: tell about failure
break
}
}
}
func setProfileData(userEmail: String? = nil, userPhone: String? = nil, userLoyaltyId: String? = nil, completion: @escaping (Result<Void, SDKError>) -> Void) {
completion(.success(Void()))
}
func track(event: Event, completion: @escaping (Result<Void, SDKError>) -> Void) {
completion(.success(Void()))
}
func recommend(blockId: String, currentProductId: String?, completion: @escaping (Result<RecommenderResponse, SDKError>) -> Void) {
}
func search(query: String, searchType: String, completion: @escaping(Result<SearchResponse, SDKError>) -> Void) {
}
private func sendInitRequest(completion: @escaping (Result<String, SDKError>) -> Void) {
let completion: (Result<String, SDKError>) -> Void = { result in
DispatchQueue.main.async { completion(result) }
}
let url = URL(string: "https://" + self.apiHost + "init_script?ssid=" + self.userSession + "&shop_id=" + self.shopId)!
let task = urlSession.dataTask(with: url, completionHandler: { data, response, error in
guard error == nil else { return completion(.failure(.initializationFailed)) }
guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
return completion(.failure(.initializationFailed))
}
guard
let mime = httpResponse.mimeType,
mime == "application/json",
let data = data,
let json = try? JSONSerialization.jsonObject(with: data),
let jsonObject = json as? [String: Any],
let ssid = jsonObject["ssid"] as? String
else {
return completion(.failure(.initializationFailed))
}
completion(.success(ssid))
})
// Run init request
task.resume();
}
private func sendUserInitRequest(completion: @escaping (Result<String, SDKError>) -> Void) {
// completion(.success(ssid))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment