Skip to content

Instantly share code, notes, and snippets.

@rldaulton
Created August 16, 2017 15:57
Show Gist options
  • Save rldaulton/5d9956d75b18f07d041699f88acff6a1 to your computer and use it in GitHub Desktop.
Save rldaulton/5d9956d75b18f07d041699f88acff6a1 to your computer and use it in GitHub Desktop.
A simple Swift network management file
//
// NetworkManager.swift
//
// Created by Ryan Daulton on 8/15/17.
// Copyright © 2017 Ryan Daulton. All rights reserved.
//
import Foundation
import Alamofire
import SwiftyJSON
enum Endpoint {
case getAllObjects
case getObjectById(Id: String)
// MARK: - Public Properties in case we expand this
var method: Alamofire.HTTPMethod {
switch self {
case .getAllObjects:
return .get
case .getObjectById:
return .get
}
}
var url: URLConvertible {
let baseUrl = URL.getBaseUrl()
switch self {
case .getAllObjects:
return baseUrl.appendingPathComponent("/all")
case .getObjectById(let Id):
return baseUrl.appendingPathComponent("/\(Id)")
}
}
}
private extension URL {
static func getBaseUrl() -> URL {
guard let info = Bundle.main.infoDictionary,
let urlString = info["Base URL"] as? String,
let url = URL(string: urlString) else {
fatalError("Cannot get base url from info.plist")
}
return url
}
}
final class ObjectAPI {
// MARK: - Public Methods
func getAllObjectItems(completionHandler: @escaping (_ responseObject: Data?, _ error: Error?) -> ()) {
Alamofire.request(Endpoint.getAllObjects.url).responseData { response in
debugPrint("All Response Info: \(response)")
guard let data = response.result.value, response.error == nil else {
completionHandler(nil, response.error)
return
}
completionHandler(data, nil)
}
}
func getObjectItemByID(ID: String, completionHandler: @escaping (_ responseObject: Data?, _ error: Error?) -> ()) {
Alamofire.request(Endpoint.getObjectById(Id: ID).url).responseData { response in
debugPrint("All Response Info: \(response)")
guard let data = response.result.value, response.error == nil else {
completionHandler(nil, response.error)
return
}
completionHandler(data, nil)
}
}
}
@rldaulton
Copy link
Author

rldaulton commented Aug 16, 2017

Example Use of Above Network Manager

Begin by creating some sort of DataManager class and initialize it from the AppDelegate using an Activate() method:

class DataManager {
    
    static fileprivate(set) var `default`: DataManager! = nil
    
    
    // MARK: Properties
    
    private(set) var items: [Items] = []
    
    static var items: [Items] {
        return `default`.items
    }
    
    
    // MARK: Instance - Activation
    
    static func Activate() {
        DispatchQueue.High.async { DataManager.default = DataManager() }
    }

. . . 

Then, using a private initializer, call a parsed() method to begin pulling & parsing data from your endpoint. A post notification is thrown on completion, which can be received elsewhere in your app to handle the ingested data.

    private init() {
        self.parsed({ items in
            self.items.append(contentsOf: items)
            NotificationCenter.default.post( Notification(name: DataManager.parseComplete) )
        })
    }

. . . 

An example of the parsing function that uses your Network Manager:

    private func parsed(_ completionHandler: @escaping (_ items: [Items]) -> ()) {
        
        ObjectAPI(). getAllObjectItems(completionHandler: { (responseObject, error) in
            guard let array = JSON(data: responseObject!).array else {
                print("[ERROR]:",error ?? "method 'parsed()' failed")
                fatalError(Error.ItemsIsNotArray)
            }
            let items = array.flatMap { Items(json: $0) }
            
            defer {
                DataManager.archive(items: items)
            }
            completionHandler(items)
        })
    }

And finally, here would be an example of the remaining file structure to wrap up the DataManager class and include some helpful extensions:

. . . 

// MARK: Archiving
    
    private static let Archive = "Items_Archive"
    private static let ArchivePath = Directory.Documents.appendingPathComponent(Archive).path
    
    private static func archive(items: [Item]) {
        
        Dispatch.queue(.Background).async {
            NSKeyedArchiver.archiveRootObject(items, toFile: DataManager.ArchivePath)
        }
    }
    
    private static func unarchive() -> [Item]? {
        return NSKeyedUnarchiver.unarchiveObject(withFile: DataManager.ArchivePath) as? [Item]
    }
    
}


// MARK: - Key Helpers

// Private Keys For JSON Data Ingestion

fileprivate struct Error {
    
    static let ItemsIsNotArray = "Items is not an array."
    
}


// MARK: - Notification Extensions

extension Notification.Name {
    
    typealias DataManager = Notification.Name
    
}

extension DataManager {
    
    static let parseComplete = Notification.Name("DataManagerParseComplete")
    
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment