Skip to content

Instantly share code, notes, and snippets.

@arpitjain03
Last active November 5, 2019 11:42
Show Gist options
  • Save arpitjain03/d08906da589db6f7d26a1ca6d3af463f to your computer and use it in GitHub Desktop.
Save arpitjain03/d08906da589db6f7d26a1ca6d3af463f to your computer and use it in GitHub Desktop.
//
// APIManager.swift
// APIManager.swift
//
// Created by Arpit Jain on 22/01/18.
// Copyright © 2018 Arpit Jain. All rights reserved.
//
//
import Foundation
import UIKit
import Alamofire
import SwiftyJSON
import SystemConfiguration
/// This is the Server End URL
let strServerBasicURL = AppConstant.ServerURL.live_development // live // development
private struct FNAPIStruct {
static let VIDEOTYPES: [String] = ["mov","m4v","mp4"]
static let AUDIOTYPES: [String] = ["mp3","caf","m4v","aac"]
static let IMAGETYPES: [String] = ["jpg","jpeg","m4a","aac"]
static let FILE_DATA: String = "file_data"
static let FILE_KEY: String = "file_key"
static let FILE_MIME: String = "file_mime"
static let FILE_EXT: String = "file_ext"
static let FILE_NAME: String = "file_name"
static let KEY_PREVIEW_APP = "is_app_preview"
}
class FNAPIManager: NSObject {
/// Structure for the Default SharedInstance of Sesstion Manager which will be used to call webservice
struct APIManager {
static let shared: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 60.0 // Seconds
configuration.timeoutIntervalForResource = 60.0 // Seconds
return Alamofire.SessionManager(configuration: configuration)
}()
}
//MARK: - Network Reachability
/**
Network Reachability
- parameter reachableBlock: reachableBlock description
*/
class func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection)
}
/// This method is used to Cancel all API call
class func stopAllAPICall() -> Void {
APIManager.shared.session.getTasksWithCompletionHandler { (dataTast, uploadTask, downloadTask) in
dataTast.forEach { $0.cancel() }
uploadTask.forEach { $0.cancel() }
downloadTask.forEach { $0.cancel() }
}
}
//MARK: - GET Service
/**
GET Web Service Method
- parameter url: API URL String
- parameter param: Parameter description
- parameter controller: Object of UIViewController
- parameter completionSuccessBlock: completionSuccessBlock description
- parameter completionFailureBlock: completionFailureBlock description
### Usage Example: ###
````
FNAPIManager.GET(strPostURL, param: nil, controller: self, successBlock: { (jsonResponse) in
print("success response is received")
}) { (error, isTimeOut) in
if isTimeOut {
print("Request Timeout")
} else {
print(error?.localizedDescription)
}
}
````
*/
class func GET(_ url: String,
param: [String: Any]?,
controller: UIViewController,
successBlock: @escaping (_ response: JSON) -> Void,
failureBlock: @escaping (_ error: Error? , _ isTimeOut: Bool) -> Void) {
if FNAPIManager.isConnectedToNetwork() {
// Internet is connected
var headers = [
"Accept": "application/json"
]
if let strToken:String = UserManager.getAccessToken()
{
headers["accesstoken"] = strToken
}
let aStrURl = strServerBasicURL + url
print("---- GET REQUEST URL : \(aStrURl)")
print("---- GET REQUEST PARAM : \(param ?? ["":""])")
APIManager.shared.request(aStrURl, method: .get, parameters: param, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler: { (response) in
print("---- GET REQUEST URL RESPONSE : \(url)\n\(response.result)")
print(response.timeline)
switch response.result {
case .success:
// print(response.request) // original URL request
// print(response.response) // HTTP URL response
// print(response.data) // server data
if let aJSON = response.result.value {
let json = JSON(aJSON)
print("---- GET SUCCESS RESPONSE : \(json)")
successBlock(json)
}
case .failure(let error):
print(error)
if (error as NSError).code == -999 {
// Request has been cancelled by the User
} else {
MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
}
failureBlock(error, false)
// if (error as NSError).code == -1001 {
// // The request timed out error occured. // Code=-1001 "REQUEST_TIMED_OUT"
// MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
// // UIAlertController.showAlertWithOkButton(controller: controller, aStrMessage: "REQUEST_TIMED_OUT", completion: nil)
// failureBlock(error, true)
// } else if (error as NSError).code == 3840 {
// MessageBar.show(.error, strMessage: "RESPONSE_INVALID")
// failureBlock(error, false)
// } else {
// MessageBar.show(.error, strMessage: error.localizedDescription)
// // UIAlertController.showAlertWithOkButton(controller: controller, aStrMessage: error.localizedDescription, completion: nil)
// failureBlock(error, false)
// }
}
})
} else {
// Internet is not connected
MessageBar.show(.error, strMessage: "INTERNET_NOT_AVAILABLE")
let aErrorConnection = NSError(domain: "InternetNotAvailable", code: 0456, userInfo: nil)
failureBlock(aErrorConnection as Error , false)
}
}
//MARK: - POST Service
/**
POST Web Service Method
- parameter url: API URL String
- parameter param: Parameter description
- parameter controller: Object of UIViewController
- parameter completionSuccessBlock: completionSuccessBlock description
- parameter completionFailureBlock: completionFailureBlock description
### Usage Example: ###
````
FNAPIManager.POST(strPostURL, param: aDictParam, controller: self, successBlock: { (jsonResponse) in
print("success response is received")
}) { (error, isTimeOut) in
if isTimeOut {
print("Request Timeout")
} else {
print(error?.localizedDescription)
}
}
````
*/
class func POST(_ url: String,
param: [String: Any],
controller: UIViewController,
successBlock: @escaping (_ response: JSON) -> Void,
failureBlock: @escaping (_ error: Error? , _ isTimeOut: Bool) -> Void) {
if FNAPIManager.isConnectedToNetwork() {
// Internet is connected
var headers = [
"content-type": "application/json"
]
if let strToken:String = UserManager.getAccessToken()
{
headers["accesstoken"] = strToken
}
let aStrURl = strServerBasicURL + url
print("---- POST REQUEST URL : \(aStrURl)")
print("---- POST REQUEST PARAM : \(param)")
APIManager.shared.request(aStrURl, method: .post, parameters: param, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler: { (response) in
print("---- POST RESPONSE URL : \(aStrURl)\n\(response.result)")
print(response.timeline)
switch response.result {
case .success:
// print(response.request) // original URL request
// print(response.response) // HTTP URL response
// print(response.data) // server data
if let aJSON = response.result.value {
let json = JSON(aJSON)
print("---- POST SUCCESS RESPONSE : \(json)")
successBlock(json)
}
case .failure(let error):
print(error)
if (error as NSError).code == -999 {
// Request has been cancelled by the User
} else {
MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
}
failureBlock(error, false)
// if (error as NSError).code == -1001 {
// // The request timed out error occured. // Code=-1001 "REQUEST_TIMED_OUT"
// MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
// failureBlock(error, true)
// } else if (error as NSError).code == 3840 {
// MessageBar.show(.error, strMessage: "RESPONSE_INVALID")
// failureBlock(error, false)
// } else if (error as NSError).code == -1005 {
// MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
// failureBlock(error, false)
// } else if (error as NSError).code == -999 {
// // Request has been cancelled by the User
// failureBlock(error, false)
// } else {
// MessageBar.show(.error, strMessage: error.localizedDescription)
// failureBlock(error, false)
// }
}
})
} else {
// Internet is not connected
MessageBar.show(.error, strMessage: "INTERNET_NOT_AVAILABLE")
let aErrorConnection = NSError(domain: "InternetNotAvailable", code: 0456, userInfo: nil)
failureBlock(aErrorConnection as Error , false)
}
}
//MARK: - UPLOAD Service
/**
UPLOAD Web Service
- parameter url: url description
- parameter param: param description
- parameter completionSuccessBlock: completionSuccessBlock description
- parameter completionFailureBlock: completionFailureBlock description
### Usage Example: ###
````
let aDictParameter: [String: Any] = [
"email": "[email protected]" as Any,
"relationship_status": "Single" as Any,
"doc_url": <Pass URL of file here> as Any,
"profile_img": UIImage.init(named: "img-sharewith-bg@3x")!,
"ParamName": "profile_img,doc_url" as Any
]
FNAPIManager.UPLOAD(strPostURL, param: aDictParameter, controller: self, successBlock: { (jsonResponse) in
print("success response is received")
}) { (error, isTimeOut) in
if isTimeOut {
print("Request Timeout")
} else {
print(error?.localizedDescription)
}
````
- Remark:
You have to pass all the "keys" seperated by comma(,) for "ParamName" key which is having Image or File
*/
class func UPLOAD(_ url: String,
param: [String: Any],
controller: UIViewController,
progressBlock: @escaping (_ progress: Progress) -> Void,
successBlock: @escaping (_ response: JSON) -> Void,
failureBlock: @escaping (_ error: Error? , _ isTimeOut: Bool) -> Void) {
let aStrURl = strServerBasicURL + url
/*
// Sample Request has to be like this :
let aDictTem: [String: Any] = [
"email":"[email protected]" as Any,
"relationship_status" : "Single" as Any,
"doc_url" : <Pass URL of file here> as Any,
"profile_img":UIImage.init(named: "img-sharewith-bg@3x")!,
"ParamName":"profile_img,doc_url" as Any]
*/
if FNAPIManager.isConnectedToNetwork() {
// MMSwiftSpinner.show("Uploading...")
var aParam = param
var arrKeys: [String] = [String]()
if let paramNameKey = aParam["ParamName"] as? String {
arrKeys = paramNameKey.components(separatedBy: ",")
}
var arrMutData = [ [String: Any] ]()
for strKey in arrKeys {
var dictRequestPatamData = [String: Any]()
print(aParam[strKey]!)
if aParam[strKey]! is UIImage {
let image = aParam[strKey] as! UIImage
// let imageData: Data = UIImageJPEGRepresentation(image, 0.5)!
let imageData: Data = (image.mediumQualityJPEGNSData)
dictRequestPatamData[FNAPIStruct.FILE_DATA] = imageData
dictRequestPatamData[FNAPIStruct.FILE_KEY] = strKey
dictRequestPatamData[FNAPIStruct.FILE_NAME] = "\(strKey).png"
dictRequestPatamData[FNAPIStruct.FILE_MIME] = "image/jpeg"
dictRequestPatamData[FNAPIStruct.FILE_EXT] = "png"
} else if aParam[strKey]! is NSURL || aParam[strKey]! is URL {
let aURL = aParam[strKey] as! URL
do {
if try aURL.checkResourceIsReachable() {
let strFileName: String = aURL.absoluteURL.lastPathComponent
let strFileType = strFileName.components(separatedBy: ".").last
if let fileData = try? Data(contentsOf: aURL) {
// Data is received from URL
dictRequestPatamData[FNAPIStruct.FILE_DATA] = fileData
dictRequestPatamData[FNAPIStruct.FILE_KEY] = strKey
dictRequestPatamData[FNAPIStruct.FILE_NAME] = strFileName
if strFileType?.lowercased() == "pdf" {
dictRequestPatamData[FNAPIStruct.FILE_MIME] = "application/pdf"
dictRequestPatamData[FNAPIStruct.FILE_EXT] = "pdf"
} else if strFileType?.lowercased() == "doc" {
dictRequestPatamData[FNAPIStruct.FILE_MIME] = "application/msword"
dictRequestPatamData[FNAPIStruct.FILE_EXT] = "doc"
} else if strFileType?.lowercased() == "docx" {
dictRequestPatamData[FNAPIStruct.FILE_MIME] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
dictRequestPatamData[FNAPIStruct.FILE_EXT] = "docx"
} else if strFileType?.lowercased() == "txt" {
dictRequestPatamData[FNAPIStruct.FILE_MIME] = "text/plain"
dictRequestPatamData[FNAPIStruct.FILE_EXT] = "txt"
} else if (FNAPIStruct.IMAGETYPES.contains((strFileType?.lowercased())!)) {
let img : UIImage = UIImage(data: fileData)!
// let imageData: Data = UIImageJPEGRepresentation(img, 0.5)!
let imageData: Data = (img.mediumQualityJPEGNSData)
dictRequestPatamData[FNAPIStruct.FILE_DATA] = imageData
dictRequestPatamData[FNAPIStruct.FILE_MIME] = "image/jpeg"
dictRequestPatamData[FNAPIStruct.FILE_EXT] = "png"
} else if (FNAPIStruct.AUDIOTYPES.contains((strFileType?.lowercased())!)) {
dictRequestPatamData[FNAPIStruct.FILE_MIME] = "Audio/mp3"
dictRequestPatamData[FNAPIStruct.FILE_EXT] = "mp3"
} else if (FNAPIStruct.VIDEOTYPES.contains((strFileType?.lowercased())!)) {
dictRequestPatamData[FNAPIStruct.FILE_MIME] = "video/mov"
dictRequestPatamData[FNAPIStruct.FILE_EXT] = "mov"
}
} else {
// Data is not received from URL
print("Something went wrong. Unable to Get Data from the URL : \(aURL)")
}
}
}
catch {
//Handle error
print("Exception is occurred. Unable to Get Data from the URL")
}
}
arrMutData.append(dictRequestPatamData)
aParam.removeValue(forKey: strKey)
}
aParam.removeValue(forKey: "ParamName")
// let headers = [
// "Content-Type": "application/json"
// ]
print("---- POST REQUEST URL : \(aStrURl)")
print("---- POST REQUEST PARAM : \(aParam)")
APIManager.shared.upload(multipartFormData: { (multipartFormData) in
for dict in arrMutData {
let aData = dict[FNAPIStruct.FILE_DATA] as! Data
let strKey = dict[FNAPIStruct.FILE_KEY] as! String
let strName = dict[FNAPIStruct.FILE_NAME] as! String
let strMime = dict[FNAPIStruct.FILE_MIME] as! String
multipartFormData.append(aData, withName: strKey, fileName: strName, mimeType: strMime)
}
for (key, value) in aParam {
if value is String {
let aStrValue = value as! String
multipartFormData.append(aStrValue.data(using: .utf8)!, withName: key)
} else if value is Dictionary<String, Any> {
let a1dict = value as! [String: Any]
for (key1, value1) in a1dict {
if value1 is String {
let aStrValue1 = value1 as! String
multipartFormData.append(aStrValue1.data(using: .utf8)!, withName: key1)
}
}
}
}
}, to: aStrURl, encodingCompletion: { (encodingResult) in
switch encodingResult {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
// Update progress indicator
// print(progress.fractionCompleted)
progressBlock(progress)
})
upload.responseJSON { response in
print(response.timeline)
if let aJSON = response.result.value {
let json = JSON(aJSON)
print("---- UPLOAD SUCCESS RESPONSE : \(json)")
successBlock(json)
}
}
case .failure(let error):
print(error)
if (error as NSError).code == -999 {
// Request has been cancelled by the User
} else {
MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
}
failureBlock(error, false)
// if (error as NSError).code == -1001 {
// // The request timed out error occured. // Code=-1001 "REQUEST_TIMED_OUT"
// MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
// UIAlertController.showAlertWithOkButton(controller: controller, aStrMessage: "REQUEST_TIMED_OUT", completion: nil)
// failureBlock(error, true)
// } else {
// MessageBar.show(.error, strMessage: error.localizedDescription)
// UIAlertController.showAlertWithOkButton(controller: controller, aStrMessage: error.localizedDescription, completion: nil)
// failureBlock(error, false)
// }
}
})
} else {
// Internet is not connected
MessageBar.show(.error, strMessage: "INTERNET_NOT_AVAILABLE")
let aErrorConnection = NSError(domain: "InternetNotAvailable", code: 0456, userInfo: nil)
failureBlock(aErrorConnection as Error , false)
}
}
/*
class func POST(_ url: String,
param: [String: Any],
controller: UIViewController,
successBlock: @escaping (_ response: JSON) -> Void,
failureBlock: @escaping (_ error: Error? , _ isTimeOut: Bool) -> Void) {*/
class func WSPostAPIMultiPart(url : String,
params : [String:Any],
controller: UIViewController,
progressBlock: @escaping (_ progress: Progress) -> Void,
successBlock: @escaping (_ response: JSON) -> Void,
failureBlock: @escaping (_ error: Error? , _ isTimeOut: Bool) -> Void) {
let aStrURl = strServerBasicURL + url
if isConnectedToNetwork() {
// let headers = [
// "Accept": "application/json"
// ]
var headers:[String:String] = [
"content-type":"multipart/form-data"
]
if let strToken:String = UserManager.getAccessToken()
{
headers["accesstoken"] = strToken
}
// SVProgressHUD.show(withStatus: "Preparing files...")
print("---- POST REQUEST URL : \(aStrURl)")
print("---- POST REQUEST PARAM : \(params)")
Alamofire.upload(multipartFormData: { (formData) in
for (key, value) in params {
if let url = value as? URL{
formData.append(url, withName: key)
}else if let image = value as? UIImage{
let data = UIImageJPEGRepresentation(image, 1.0)
formData.append(data!, withName: key, fileName: "profile_image.jpeg", mimeType: "image/jpeg")
}else{
formData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}
}, to: aStrURl , method : .post , headers : headers) { (response) in
switch response {
case .success(let upload, _, _):
// SVProgressHUD.dismiss()
// SVProgressHUD.show(withStatus: "Uploading...")
upload.uploadProgress(closure: { (progress) in
progressBlock(progress)
})
upload.responseJSON { response in
// SVProgressHUD.dismiss()
print(response.timeline)
if let aJSON = response.result.value {
let json = JSON(aJSON)
print("---- UPLOAD SUCCESS RESPONSE : \(json)")
successBlock(json)
}
}
case .failure(let error):
print(error)
if (error as NSError).code == -1001 {
MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
} else {
MessageBar.show(.error, strMessage: "SOMETHING_WENT_WRONG")
}
}
}
}
else {
MessageBar.show(.error, strMessage: "INTERNET_NOT_AVAILABLE")
// failureBlock(aErrorConnection as Error , false)
}
}
class func WSGetAPIMultiPart(url : String,
params : [String:Any],
progressBlock: @escaping (_ progress: Progress) -> Void,
successBlock: @escaping (_ response: JSON) -> Void,
failureBlock: @escaping (_ error: Error? , _ isTimeOut: Bool) -> Void) {
let aStrURl = strServerBasicURL + url
if isConnectedToNetwork() {
// let headers = [
// "Accept": "application/json"
// ]
var headers:[String:String] = [
"content-type":"multipart/form-data"
]
if let strToken:String = UserManager.getAccessToken()
{
headers["accesstoken"] = strToken
}
// SVProgressHUD.show(withStatus: "Preparing files...")
print("---- Get REQUEST URL : \(aStrURl)")
print("---- Get REQUEST PARAM : \(params)")
Alamofire.upload(multipartFormData: { (formData) in
for (key, value) in params {
if let url = value as? URL{
formData.append(url, withName: key)
}else if let image = value as? UIImage{
let data = UIImageJPEGRepresentation(image, 1.0)
formData.append(data!, withName: key, fileName: "profile_image.jpeg", mimeType: "image/jpeg")
}else{
formData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}
}, to: aStrURl , method : .get , headers : headers) { (response) in
switch response {
case .success(let upload, _, _):
// SVProgressHUD.dismiss()
// SVProgressHUD.show(withStatus: "Uploading...")
upload.uploadProgress(closure: { (progress) in
progressBlock(progress)
})
upload.responseJSON { response in
// SVProgressHUD.dismiss()
print(response.timeline)
if let aJSON = response.result.value {
let json = JSON(aJSON)
print("---- UPLOAD SUCCESS RESPONSE : \(json)")
successBlock(json)
}
}
case .failure(let error):
print(error)
if (error as NSError).code == -1001 {
MessageBar.show(.error, strMessage: "REQUEST_TIMED_OUT")
} else {
MessageBar.show(.error, strMessage: "SOMETHING_WENT_WRONG")
}
}
}
}
else {
MessageBar.show(.error, strMessage: "INTERNET_NOT_AVAILABLE")
// failureBlock(aErrorConnection as Error , false)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment