Advertisement
Guest User

Untitled

a guest
Sep 18th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 4.71 KB | None | 0 0
  1. //
  2. //  TGStationSearchWorker.swift
  3. //  TicketCleverGo
  4. //
  5. //  Created by Anh Phan Tran on 06/08/2018.
  6. //  Copyright © 2018 The Distance. All rights reserved.
  7. //
  8.  
  9. import Foundation
  10. import Promises
  11.  
  12. protocol TGStationSearchWorkerProtocol {
  13.   func getStations(for searchString: String, onlyRecent: Bool) -> Promise<[TGStation]>
  14. }
  15.  
  16. class TGStationSearchWorker: TGStationSearchWorkerProtocol {
  17.   var localDBService: TGLocalDBServiceProtocol
  18.  
  19.   init(localDBService: TGLocalDBServiceProtocol) {
  20.     self.localDBService = localDBService
  21.   }
  22.  
  23.   func sort(_ stations: [TGStation], with key: String) -> [TGStation] {
  24.     var crsStations = [TGStation]()
  25.     var name1stWordStations = [TGStation]()
  26.     var name2ndWordStations = [TGStation]()
  27.     var name3rdWordStations = [TGStation]()
  28.     var remainingStations = [TGStation]()
  29.    
  30.     for station in stations {
  31.       if key.hasPrefix(station.crs, caseInsensitive: false) {
  32.         crsStations.append(station)
  33.       } else if station.name.word(at: 0).hasPrefix(key, caseInsensitive: false) {
  34.         name1stWordStations.append(station)
  35.       } else if station.name.word(at: 1).hasPrefix(key, caseInsensitive: false) {
  36.         name2ndWordStations.append(station)
  37.       } else if station.name.word(at: 2).hasPrefix(key, caseInsensitive: false) {
  38.         name3rdWordStations.append(station)
  39.       } else {
  40.         remainingStations.append(station)
  41.       }
  42.     }
  43.  
  44.     try? name1stWordStations.sort(by: self.stationNameAlphabeticalOrderSort)
  45.     try? name2ndWordStations.sort(by: self.stationNameAlphabeticalOrderSort)
  46.     try? name3rdWordStations.sort(by: self.stationNameAlphabeticalOrderSort)
  47.     try? remainingStations.sort(by: self.stationNameAlphabeticalOrderSort)
  48.    
  49.     return crsStations + name1stWordStations + name2ndWordStations + name3rdWordStations + remainingStations
  50.   }
  51.  
  52.   func stationNameAlphabeticalOrderSort(lhs: TGStation, rhs: TGStation) throws -> Bool {
  53.     return lhs.name < rhs.name
  54.   }
  55.  
  56.   func getStations(for key: String, onlyRecent: Bool) -> Promise<[TGStation]> {
  57.     if key.isEmpty {
  58.       let recentStations = TGLocalData.shared.recentStations
  59.       if onlyRecent {
  60.         return Promise(Array(recentStations))
  61.       } else {
  62.         return self.localDBService.fetchStations().then { stations -> [TGStation] in
  63.           if !recentStations.isEmpty {
  64.             var returningStations = stations
  65.             if let mostRecentStation = recentStations.first, let index = returningStations.index(of: mostRecentStation) {
  66.               returningStations.remove(at: index)
  67.               returningStations.insert(mostRecentStation, at: 0)
  68.             }
  69.             if recentStations.count >= 2 {
  70.               let secondMostRecentStation = returningStations[1]
  71.               if let index = returningStations.index(of: secondMostRecentStation) {
  72.                 returningStations.remove(at: index)
  73.                 returningStations.insert(secondMostRecentStation, at: 1)
  74.               }
  75.             }
  76.             return returningStations
  77.           } else {
  78.             return stations
  79.           }
  80.         }
  81.       }
  82.     } else if key.count < 3 {
  83.       let predicate = NSPredicate(format: "crs BEGINSWITH[cd] %@ OR name CONTAINS[cd] %@", key, key)
  84.       if onlyRecent {
  85.         let filtered = TGLocalData.shared.recentStations.filter(predicate).sorted(byKeyPath: "name", ascending: true)
  86.         return Promise(Array(filtered))
  87.       } else {
  88.         return self.localDBService.queryStations(with: predicate)
  89.       }
  90.     } else {
  91.       // 1. CRS/Name Filter:
  92.       return Promise<[TGStation]>() { fullfill, reject in
  93.         let predicate = NSPredicate(format: "crs BEGINSWITH[cd] %@ OR name CONTAINS[cd] %@", key, key)
  94.         if onlyRecent {
  95.           let filtered = TGLocalData.shared.recentStations.filter(predicate)
  96.           fullfill(Array(filtered))
  97.         } else {
  98.           self.localDBService.queryStations(with: predicate).then { filtered in
  99.             fullfill(filtered)
  100.           }
  101.         }
  102.         }
  103.         // 2. Plugin suggestions:
  104.         .then { filtered -> [TGStation] in
  105.           let sortedStations = self.sort(filtered, with: key)
  106.           var results = sortedStations
  107.           var offset = 0
  108.          
  109.           for (index, station) in sortedStations.enumerated() {
  110.             for suggestion in station.searchSuggestions.reversed() {
  111.               if let suggestedStation = self.localDBService.getStation(withCrs: suggestion) {
  112.                 if !results.contains(suggestedStation) {
  113.                   results.insert(suggestedStation, at: index + 1 + offset)
  114.                   offset += 1
  115.                 }
  116.               }
  117.             }
  118.           }
  119.          
  120.           return results
  121.       }
  122.     }
  123.   }
  124. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement