Created
March 12, 2018 08:21
-
-
Save madcato/d5c6ed09ca2792707365055ed1302690 to your computer and use it in GitHub Desktop.
EoloSender is a class to send POST to a http server. If the request fails, it's stored. It tries to resend the request every 15 seconds. Methods must be called from applicationDidBecomeActive and applicationWillResignActive, see the code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// EoloSender.swift | |
// OSFramework | |
// | |
// Created by Daniel Vela on 13/02/17. | |
// Copyright © 2016 Daniel Vela. All rights reserved. | |
// | |
import Foundation | |
public protocol EoloSenderInteractor { | |
func postJSON(url: String, | |
parameters: [String: Any], | |
onOK: @escaping (Any?) -> Void, | |
onError: @escaping (Int, String) -> Void) | |
func cancel() | |
} | |
/*! | |
EoloSender is a class to send POST to a http server. If the request | |
fails, it's stored. It tries to resend the request every 15 seconds. | |
Methods must be called from applicationDidBecomeActive and | |
applicationWillResignActive, see the code. | |
*/ | |
public class EoloSender { | |
var fileName = "WebQueriesData" | |
var data: [SerializableWebQuery] = [] | |
var running = false | |
var senderObject: EoloSenderInteractor | |
public init(senderObject: EoloSenderInteractor) { | |
self.senderObject = senderObject | |
} | |
public func append(_ url: String, parameters: [String: Any]) { | |
self.data.append(SerializableWebQuery(url: url, | |
parameters: parameters, | |
sender: self.senderObject)) | |
startContinue() | |
} | |
// Call this method from applicationDidBecomeActive | |
public func appBecomeActive() { | |
let restoredObjects = Serializator().restoreObject(fileName: fileName) | |
if let restoredObjects = restoredObjects { | |
self.data = restoredObjects as? [SerializableWebQuery] ?? [] | |
for object in self.data { | |
object.sender = self.senderObject | |
} | |
} | |
startContinue() | |
} | |
// Call this method from applicationWillResignActive | |
public func appBecomeInactive() { | |
Serializator().saveObject(object: self.data as AnyObject, fileName: fileName) | |
} | |
func startContinue() { | |
if running == false { | |
running = true | |
} else { | |
return | |
} | |
sendAQuery() | |
} | |
static let initialSecondsToWaitOnError: Double = 15.0 | |
var secondsToWaitOnError = { | |
initialSecondsToWaitOnError | |
}() | |
func sendAQuery() { | |
DispatchQueue.global(qos: .background).async { | |
if self.data.count > 0 { | |
let webQuery = self.data.removeFirst() | |
webQuery.start({ | |
// Nothing. The query was ok | |
// Continue with next one | |
self.sendAQuery() | |
self.secondsToWaitOnError = EoloSender.initialSecondsToWaitOnError | |
// print("Pairing registered", webQuery.parameters) | |
}, onError: { | |
// On error the query must be restored on the queue | |
DispatchQueue.global(qos: .background).async { | |
self.data.append(webQuery) | |
// and wait some seconds | |
Thread.sleep(forTimeInterval: self.secondsToWaitOnError) | |
self.sendAQuery() | |
} | |
// print("Pairing error", webQuery.parameters) | |
}) | |
} else { | |
self.running = false | |
} | |
} | |
} | |
} | |
class SerializableWebQuery: NSObject, NSCoding { | |
var url: String | |
var parameters: [String: Any] | |
var sender: EoloSenderInteractor? | |
init(url: String, parameters: [String: Any], sender: EoloSenderInteractor) { | |
self.url = url | |
self.parameters = parameters | |
self.sender = sender | |
} | |
func start(_ onOK: @escaping () -> Void, onError: @escaping () -> Void ) { | |
sender?.postJSON(url: self.url, | |
parameters: self.parameters, | |
onOK: { (_) in | |
// Revome this object in Serrializable data | |
onOK() | |
}, | |
onError: { (_, _) in | |
// Keep this object in seriliable data | |
onError() | |
}) | |
} | |
func stop() { | |
sender?.cancel() | |
} | |
required init?(coder aDecoder: NSCoder) { | |
self.url = aDecoder.decodeObject(forKey: "url") as? String ?? "" | |
self.parameters = aDecoder.decodeObject(forKey: "parameters") | |
as? [String: Any] ?? [:] | |
} | |
func encode(with aCoder: NSCoder) { | |
self.stop() | |
aCoder.encode(self.url, forKey: "url") | |
aCoder.encode(self.parameters, forKey: "parameters") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment