vendoo_v1.0/Vendoo/EtsyRESTAPIManager.swift
Okechi Onyeje bfd4832b7d Error Messages Set Up
- for ebay service getting items and authentication
2017-01-25 18:45:03 -05:00

801 lines
43 KiB
Swift

//
// EtsyRESTConnectionManager.swift
// Vendoo
//
// Created by Okechi Onyeje on 5/25/16.
// Copyright © 2016 Okechi Onyeje. All rights reserved.
//
//NOT ABLE TO CAPTURE NEEDED DATA FROM RESPONSE IN OAUTH PROCESS FOR ETSY
import Foundation
import SwiftyJSON
import OAuthSwift
import Locksmith
typealias ServiceResponse = (AnyObject?, AnyObject?) -> Void
class EtsyRESTAPIManager: NSObject {
//API Manager class variables
//----------------------------------------------//
static let sharedInstance = EtsyRESTAPIManager()
let baseURL = "https://openapi.etsy.com/v2"
private var apiKey: String!
private var apiSecret: String!
private var userEmail:String = (NSUserDefaults.standardUserDefaults().objectForKey("email") as? String)!
var isAuthorized: Bool = NSUserDefaults.standardUserDefaults().boolForKey("etsyAuthorized")
static var settingsDictionary = Dictionary<String , AnyObject>()
//---------------------------------------------//
//User specific class variables
private var etsyUser: String!
private var oauthswift: OAuth1Swift!
override init(){
super.init()
if let path = NSBundle.mainBundle().pathForResource("Services", ofType: "plist"), dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
// use swift dictionary as normal
self.apiKey = ((dict["Etsy"] as! Dictionary<String, AnyObject>)["consumerKey"] as! String)
self.apiSecret = ((dict["Etsy"] as! Dictionary<String, AnyObject>)["consumerSecret"] as! String)
oauthswift = OAuth1Swift(parameters: ["consumerKey":self.apiKey,"consumerSecret":self.apiSecret, "requestTokenUrl" : "https://openapi.etsy.com/v2/oauth/request_token?scope=listings_w%20listings_r%20listings_d%20transactions_r%20transactions_w",
"authorizeUrl": "https://www.etsy.com/oauth/signin?",
"accessTokenUrl": "https://openapi.etsy.com/v2/oauth/access_token?",
"responseType": "token"])
//@FIXME: something is wrong when here when logging back in with a diff user
if(self.isAuthorized){
let dictionary = Locksmith.loadDataForUserAccount(self.userEmail, inService: "vendoo_oauth_etsy")
let oauthDictionary = dictionary?["etsy_oauth"] as? Dictionary<String, AnyObject!>
print((oauthDictionary?["token"] as? String!)!)
self.oauthswift.client.credential.oauth_token = (oauthDictionary?["token"] as? String!)!
self.oauthswift.client.credential.oauth_token_secret = (oauthDictionary?["secret"] as? String!)!
//used to get all etsy categories if user is authorized
self.sendGETRequest("/taxonomy/categories", onCompletion: {
(dict, error) -> Void in
var resultDictionary = Dictionary<String, AnyObject>()
for catDictionary in (dict as! [Dictionary<String, AnyObject>]) {
print(catDictionary)
resultDictionary[catDictionary["name"] as! String] = catDictionary["category_id"] as! Int
}
EtsyRESTAPIManager.settingsDictionary["categories"] = resultDictionary
NSUserDefaults.standardUserDefaults().setObject(EtsyRESTAPIManager.settingsDictionary, forKey: "etsySettings")
})
}
//sets up posting defaults when posting to etsy
if(NSUserDefaults.standardUserDefaults().boolForKey("etsyDefaultsOverriden")) {
EtsyRESTAPIManager.settingsDictionary = (NSUserDefaults.standardUserDefaults().objectForKey("etsySettings") as? Dictionary<String, AnyObject>)!
}
else{
EtsyRESTAPIManager.settingsDictionary = ([
"who_made":"i_did",
"is_supply":true,
"when_made":"made_to_order"
] as Dictionary<String, AnyObject>)
NSUserDefaults.standardUserDefaults().setObject(EtsyRESTAPIManager.settingsDictionary, forKey: "etsySettings")
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "etsyDefaultsOverriden")
}
}
}
}
//Mark: - OAuth Methods
extension EtsyRESTAPIManager {
//makes application ready for use with users etsy account
func authorizeApp(viewcontroller: UIViewController, onComplete: ServiceResponse!){
var boolResult: Bool!
if(!isAuthorized){
oauthswift!.authorize_url_handler = SafariURLHandler(viewController: viewcontroller)
//start oauth handshake
self.oauthswift!.client.get("https://openapi.etsy.com/v2/oauth/request_token?scope=listings_w%20listings_r%20listings_d%20transactions_r%20transactions_w",
success: {
data, response in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
let json = JSON(data)
print(json)
print(dataString)
self.oauthswift!.authorizeWithCallbackURL( NSURL(string: "vendoo://oauth-callback/etsy")!, success: {
credential, response, parameters in
print(response)
boolResult = false
}, failure: { error in
//print(error)
dispatch_async(dispatch_get_main_queue(), {() -> Void in
print(self.oauthswift!.client.credential.oauth_token)
print(self.oauthswift!.client.credential.oauth_token_secret)
print(self.oauthswift.client.credential.oauth_verifier)
print(self.oauthswift.allowMissingOauthVerifier = true)
//save data to keychain
//sign oauth token with verifier
self.oauthswift!.client.get("https://openapi.etsy.com/v2/oauth/access_token", parameters: ["oauth_verifier":(self.oauthswift.client.credential.oauth_verifier)],
success: {
data, response in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
print(response)
let json1 = JSON(response)
print(json1)
let json = JSON(data)
print(json)
print(dataString!)
//parse out token and token secret
do {
let regex = try NSRegularExpression(pattern: "[oauth_token=|oauth_token_secret=](\\w*)", options: [])
let nsString = dataString! as NSString
let all = NSRange(location: 0, length: nsString.length)
var matches : [String] = [String]()
regex.enumerateMatchesInString(nsString as String, options: NSMatchingOptions(rawValue: 0), range: all) {
(result : NSTextCheckingResult?, _, _) in
if let r = result {
let result = nsString.substringWithRange(r.range) as String
matches.append(result)
}
}
print(matches)
//save oauth credentials for current user
let oauth: Dictionary<String, AnyObject!>? = [ "token" : String(matches[1].characters.dropFirst()) , "secret" : String(matches[3].characters.dropFirst()) ]
do{
try Locksmith.saveData(["etsy_oauth" : oauth!], forUserAccount: self.userEmail, inService: "vendoo_oauth_etsy")
print("account credentials saved")
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "etsyAuthorized")
self.isAuthorized = true
boolResult = true
self.oauthswift.client.credential.oauth_token = oauth!["token"]! as! String
self.oauthswift.client.credential.oauth_token_secret = oauth!["secret"]! as! String
// get required credentials from users account to allow posting of new listings
//get user name
self.oauthswift!.client.get("https://openapi.etsy.com/v2/users/__SELF__",
success: {
data, response in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
var dict2 = (dict!["results"] as! [[String : AnyObject]])
let json1 = JSON(dataString!)
print(json1)
print(dataString)
boolResult = true
print(dict2[0]["login_name"]!)
EtsyRESTAPIManager.settingsDictionary["userID"] = dict2[0]["login_name"]!
NSUserDefaults.standardUserDefaults().setObject(EtsyRESTAPIManager.settingsDictionary, forKey: "etsySettings")
onComplete(nil,nil)
//get users payment template if one exists, if not create one for user
self.sendGETRequest("/private/shops/__SELF__/payment_templates", onCompletion: {
(data, error) -> Void in
self.sendGETRequest("/taxonomy/categories", onCompletion: {
(dict, error) -> Void in
//save retrieved categories to settings dictionary
var resultDictionary = Dictionary<String, AnyObject>()
for catDictionary in (dict as! [Dictionary<String, AnyObject>]) {
print(catDictionary)
resultDictionary[catDictionary["name"] as! String] = catDictionary["category_id"] as! Int
}
EtsyRESTAPIManager.settingsDictionary["categories"] = resultDictionary
NSUserDefaults.standardUserDefaults().setObject(EtsyRESTAPIManager.settingsDictionary, forKey: "etsySettings")
//retrieve shipping template if one exists, if not create one
self.sendGETRequest("/private/users/__SELF__/shipping/templates", onCompletion: nil)
})
})
}
, failure: { error in
print(error)
boolResult = true
}
)
}
catch{
(error)
print(error)
//could not save data to keychain
print("account credentials could not be saved")
boolResult = false
}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
}
},
failure: {
error in
print(error)
})
})
})
}
, failure: { error in
print(error)
}
)
}
}
func deAuthorizeApp(viewcontroller: UIViewController){
oauthswift!.authorize_url_handler = SafariURLHandler(viewController: viewcontroller)
oauthswift!.client.get("https://openapi.etsy.com/v2/oauth/request_token?scope=listings_w%20listings_r%20listings_d%20transactions_r%20transactions_w",
success: {
data, response in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
print(dataString!)
print(response)
}
, failure: { error in
print(error)
}
)
dispatch_async(dispatch_get_main_queue(), {() -> Void in
self.oauthswift!.authorizeWithCallbackURL( NSURL(string: "vendoo://oauth-callback/etsy")!, success: {
credential, response, parameters in
print(credential.oauth_token)
print(credential.oauth_token_secret)
print(response)
//erase all authorization variables
do {
try Locksmith.deleteDataForUserAccount(self.userEmail, inService: "vendoo_oauth_etsy")
self.oauthswift.client.credential.oauth_token = ""
self.oauthswift.client.credential.oauth_token_secret = ""
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "etsyAuthorized")
self.isAuthorized = false
print("oauth credentials deleted and app deauthorized from etsy")
}catch{
(error)
print(error)
("failed to delete credentails and deauthorize app")
}
}, failure: { error in
print(error)
dispatch_async(dispatch_get_main_queue(), {() -> Void in
//erase all authorization variables
do {
try Locksmith.deleteDataForUserAccount(self.userEmail, inService: "vendoo_oauth_etsy")
self.oauthswift.client.credential.oauth_token = ""
self.oauthswift.client.credential.oauth_token_secret = ""
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "etsyAuthorized")
self.isAuthorized = false
print("oauth credentials deleted and app deauthorized from etsy")
}catch{
(error)
print(error)
("failed to delete credentails and deauthorize app")
}
})
})
})
}
}
//MARK: - Request Methods
extension EtsyRESTAPIManager {
//the following functions are attempts to get image upload working for etsy
func sendFile(
urlPath:String,
fileName:String,
data:NSData,
completionHandler: (NSURLResponse?, NSData?, NSError?) -> Void){
var url: NSURL = NSURL(string: urlPath)!
var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request1.HTTPMethod = "POST"
let boundary = "Boundary-\(NSUUID().UUIDString)"
let fullData = photoDataToFormData(data,boundary:boundary,fileName:fileName)
request1.setValue("multipart/form-data; boundary=" + boundary,
forHTTPHeaderField: "Content-Type")
// REQUIRED!
request1.setValue(String(fullData.length), forHTTPHeaderField: "Content-Length")
request1.setValue(self.apiKey, forHTTPHeaderField: "Authorization" )
//requested.addValue(self.apiKey, forHTTPHeaderField: "API-KEY")
request1.HTTPBody = fullData
request1.HTTPShouldHandleCookies = false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(
request1,
queue: queue,
completionHandler:completionHandler)
}
func photoDataToFormData(data:NSData,boundary:String,fileName:String) -> NSData {
var fullData = NSMutableData()
// 1 - Boundary should start with --
let lineOne = "--" + boundary + "\r\n"
fullData.appendData(lineOne.dataUsingEncoding(
NSUTF8StringEncoding,
allowLossyConversion: false)!)
// 2
let lineTwo = "Content-Disposition: form-data; name=\"image\"; filename=\"" + fileName + "\"\r\n"
NSLog(lineTwo)
fullData.appendData(lineTwo.dataUsingEncoding(
NSUTF8StringEncoding,
allowLossyConversion: false)!)
// 3
let lineThree = "Content-Type: image/jpg\r\n\r\n"
fullData.appendData(lineThree.dataUsingEncoding(
NSUTF8StringEncoding,
allowLossyConversion: false)!)
// 4
fullData.appendData(data)
// 5
let lineFive = "\r\n"
fullData.appendData(lineFive.dataUsingEncoding(
NSUTF8StringEncoding,
allowLossyConversion: false)!)
// 6 - The end. Notice -- at the start and at the end
let lineSix = "--" + boundary + "--\r\n"
fullData.appendData(lineSix.dataUsingEncoding(
NSUTF8StringEncoding,
allowLossyConversion: false)!)
return fullData
}
//sends the pregenerated url as a request to api service
func sendGETRequest(request: String, onCompletion: ServiceResponse?) {
self.oauthswift.client.get(self.baseURL + request,
success: {
(data, response) -> Void in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
print(response)
switch (request) {
case "/private/shops/__SELF__/payment_templates" :
//create a payment template if none is found
if ((dict!["results"]!.isKindOfClass(NSNull.classForCoder()))) {
//@TODO: Put payment template parameters in function call
self.oauthswift.client.post(self.baseURL + "/private/shops/__SELF__/payment_templates",
parameters: [
"shop_id":"__SELF__",
],
headers: nil,
success: {
(data, response) -> Void in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
print(response)
onCompletion!(nil,nil)
},
failure: {
(error) -> Void in
print(error)
}
)
}else {
onCompletion!(nil,nil)
}
break
case "/private/users/__SELF__/shipping/templates" :
var dict2 = (dict!["results"] as! [[String : AnyObject]])
if ((dict!["results"]!.isKindOfClass(NSNull.classForCoder()))) {
//create default shipping template if none found
self.oauthswift.client.post(self.baseURL + "/private/shipping/templates",
parameters: [
"title":"vendoo_default",
"origin_country_id":209,
"primary_cost":2.00,
"secondary_cost":1.00
],
headers: nil,
success: {
(data, response) -> Void in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
print(response)
},
failure: {
(error) -> Void in
print(error)
}
)
}else {
EtsyRESTAPIManager.settingsDictionary["shipping_template_id"] = dict2[0]["shipping_template_id"]!
NSUserDefaults.standardUserDefaults().setObject(EtsyRESTAPIManager.settingsDictionary, forKey: "etsySettings")
}
break
//gets etsy categories
case "/taxonomy/categories":
var dict2 = (dict!["results"] as! [[String : AnyObject]])
onCompletion!(dict2, nil)
break
default:
break
}
},
failure: {
(error) -> Void in
print(error)
}
)
}
//gets listing info
func getListingInfo (request: String, onCompletion: ServiceResponse?) {
self.oauthswift.client.get(self.baseURL + request,
success: {
(data, response) -> Void in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
print(response)
var dict2 = (dict!["results"] as! [[String : AnyObject]])
let listingState = dict2[0]["state"] as! String
onCompletion!(["status":listingState], nil)
}, failure: {
(error) -> Void in
print(error)
}
)}
//sends the pregenerated url as a request to api service
func sendPOSTRequest(request: String, var body: [String: AnyObject]?, onCompletion: ServiceResponse?) {
//attempt to post images to etsy
/* let request = NSMutableURLRequest(URL: NSURL(string: request)!)
// Set the method to POST
request.HTTPMethod = "POST"
do {
// Set the POST body for the request
let jsonBody = try NSJSONSerialization.dataWithJSONObject(body, options: .PrettyPrinted)
request.HTTPBody = jsonBody
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
if let jsonData = data {
let json:JSON = JSON(data: jsonData)
onCompletion(json, nil)
} else {
onCompletion(nil, error)
}
})
task.resume()
} catch {
// Create your personal error
onCompletion(nil, nil)
}*/
//for posting image to etsy, currently not working
if(request.containsString("listings/") && request.containsString("/images")){
let url = NSURL(string: self.baseURL + request)!
let data: NSData = (body!["image"] as! NSData)
sendFile(self.baseURL + request,
fileName:"main.jpg",
data:data,
completionHandler: {
(response, data, error) -> Void in
// ...
NSLog("Complete: \(response)")
if(error != nil) {
onCompletion!(nil, nil)
}
}
)
//more attempts to get image uploads to etsy to work :-(
/*
let requested = NSMutableURLRequest(URL: url)
requested.HTTPMethod = "POST"
let boundary = "Boundary-\(NSUUID().UUIDString)"
//var headers = oauthswift.client.credential.makeHeaders(url, method: OAuthSwiftHTTPRequest.Method.POST, parameters: ["Content-Type":"multipart/form-data"]) // here with create the authentification headers
requested.addValue(self.apiKey, forHTTPHeaderField: "Authorization" )
//define the multipart request type
requested.addValue("\((body!["image"] as! NSData).length)", forHTTPHeaderField: "Content-Length")
requested.addValue("bytes", forHTTPHeaderField: "Content-Transfer-Encoding")
requested.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
//requested.addValue(self.apiKey, forHTTPHeaderField: "API-KEY")
requested.HTTPBody = self.oauthswift.client.multiPartBodyFromParams(body!, boundary: boundary)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(requested) { data, response, error in
if (nil != error) {
// something went wrong
print(error)
onCompletion!(nil,nil)
switch (request) {
default:
break
}
}
else {
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
print(response)
onCompletion!(nil, nil)
switch (request) {
default:
break
}
}
}
task.resume()
*/
/*
//var headers = oauthswift.client.credential.makeHeaders(url, method: OAuthSwiftHTTPRequest.Method.POST, parameters: ["Content-Type":"multipart/form-dataheader"]) // here with create the authentification headers
// here add additional headers "Content-type", etc..
requested.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
requested.addValue("\((body["image"] as! NSData).length)", forHTTPHeaderField: "Content-Length")
requested.addValue("bytes", forHTTPHeaderField: "Content-Transfer-Encoding")
//requested.addValue("form-data; name='Main Image'; filename='mainImage.jpg'", forHTTPHeaderField: "Content-Disposition")
requested.HTTPBody = self.oauthswift.client.multiPartBodyFromParams(body, boundary: "-XXX--")
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(requested) { data, response, error in
if nil != error {
// something went wrong
print(error)
onCompletion!(nil,nil)
switch (request) {
default:
break
}
}
else {
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
print(response)
onCompletion!(nil, nil)
switch (request) {
default:
break
}
}
}
task.resume()
*/
/*
body!["oauth_verifier"] = (self.oauthswift.client.credential.oauth_verifier)
//@FIXME: multipart post request is returning with oauth signature invalid for uploading image in etsy
self.oauthswift.client.postMultiPartRequest(self.baseURL + request, method: OAuthSwiftHTTPRequest.Method.POST, parameters: body!, success: {
(data, response) -> Void in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
print(response)
onCompletion!(nil, nil)
switch (request) {
default:
break
}
},
failure: {
(error) -> Void in
print(error)
//onCompletion!(nil,nil)
switch (request) {
default:
break
}
}
)
*/
}
else {
self.oauthswift.client.post(self.baseURL + request, parameters: body!, headers: nil,
success: {
(data, response) -> Void in
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
let dict = self.convertStringToDictionary(dataString! as String)
print(dict)
print(response)
switch (request) {
case "/private/shipping/templates":
break
//save new listing id from new esty posting
case "/private/listings":
var dict2 = (dict!["results"] as! [[String : AnyObject]])
print(((dict2[0]["listing_id"])!))
onCompletion!(dict2, nil)
break
default:
break
}
},
failure: {
(error) -> Void in
print(error)
switch (request) {
case "/private/shipping/templates":
break
case "/private/listings":
print(error.userInfo["Response-Body"])
if((error.userInfo["Response-Body"]!.isEqualToString("price is below listing fee."))) {
}
break
default:
break
}
}
)
}
}
}
//MARK: - JSON Methods
extension EtsyRESTAPIManager {
//converts responses from etsy to JSON dictionaries
func convertStringToDictionary(text: String) -> [String:AnyObject]? {
if let data = text.dataUsingEncoding(NSUTF8StringEncoding) {
do {
return try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String:AnyObject]
} catch let error as NSError {
print(error)
}
}
return nil
}
}