vendoo_v1.0/Vendoo/EtsyRESTAPIManager.swift
Okechi Onyeje 031a354996 Ebay Listing Now Posts both information and single image
need to rework on categories since subcategory workflow added some complications, but that will be taken care of in a bug fix task
2016-08-23 13:48:34 -04:00

731 lines
39 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?, NSError?) -> Void
class EtsyRESTAPIManager: NSObject {
//API Manager class variables
//----------------------------------------------//
static let sharedInstance = EtsyRESTAPIManager()
let baseURL = "https://openapi.etsy.com/v2/private"
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!
//private let oauthswift = OAuth1Swift(parameters: ["consumerKey":"snbs78qkfy3yqq6yhe6yv49b","consumerSecret":"4sbva4oqb6", "requestTokenUrl": "https://openapi.etsy.com/v2/oauth/request_token?scope=listings_w%20listings_r%20listings_d%20transactions_r%20transactions_w%20"])
override 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!)!
}
/*scope=listings_w%20listings_r%20listings_d%20transactions_r%20transactions_w"*/
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){
var boolResult: Bool!
if(!isAuthorized){
oauthswift!.authorize_url_handler = SafariURLHandler(viewController: viewcontroller)
/*
let authRequest = self.oauthswift.client.makeRequest("https://openapi.etsy.com/v2/oauth/request_token?", method: OAuthSwiftHTTPRequest.Method.GET, parameters: ["scope":"listings_w%20listings_r%20listings_d%20transactions_r%20transactions_w"] , headers: nil)
do{
try authRequest?.makeRequest()
}catch{
(error)
}
*/
/*["scope":"listings_w%20listings_r%20listings_d%20transactions_r%20transactions_w"]*/
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)
//print(response.allHeaderFields)
//print(dataSting)
let json = JSON(data)
print(json)
print(dataString)
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)
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
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)
//print(response.allHeaderFields)
//print(dataSting)
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)
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
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")
self.sendGETRequest("/shops/__SELF__/payment_templates", onCompletion: {
(data, error) -> Void in
self.sendGETRequest("/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
}
/*let results = regex.matchesInString(dataString! as String,
options: [], range: NSMakeRange(0, nsString.length))
print(results.map { nsString.substringWithRange($0.range)})*/
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
}
/*
*/
},
failure: {
error in
print(error)
})
//return boolResult
})
})
//getting error here when trying to retrieve the login url from the response
//var dataDictionary = self.convertStringToDictionary(dataString! as String)
//print(dataDictionary!["login_url"])
}
, failure: { error in
print(error)
}
)
}
//once everything is authorized save true value to the authorization boolean
/*
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "etsyAuthorized")
self.isAuthorized = NSUserDefaults.standardUserDefaults().boolForKey("etsyAuthorized")
*/
}
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)
//getting error here when trying to retrieve the login url from the response
//var dataDictionary = self.convertStringToDictionary(dataString! as String)
//print(dataDictionary!["login_url"])
}
, 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 {
func generateUserRequest(etsyName: String!, etsyOptions: [String]!) -> String {
//starting url for user request to api
var userRequest: String!
if(etsyName == nil || etsyName == ""){
userRequest = (baseURL + "/users/etsystore?")
}
else{
userRequest = (baseURL + "/users/" + etsyName + "?")
}
//final api request
return userRequest + "api_key=" + self.apiKey
}
func generateListingRequest(etsyListing: String!){
//starting url for listing request
}
//sends the pregenerated url as a request to api service
func sendGETRequest(request: String, onCompletion: ServiceResponse?) {
/* let request = NSMutableURLRequest(URL: NSURL(string: request)!)
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, error)
} else {
onCompletion(nil, error)
}
})
task.resume()*/
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 "/shops/__SELF__/payment_templates" :
if ((dict!["results"]!.isKindOfClass(NSNull.classForCoder()))) {
//@TODO: Put payment template parameters in function call
self.oauthswift.client.post(self.baseURL + "/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)
}
)
}
break
case "/users/__SELF__/shipping/templates" :
var dict2 = (dict!["results"] as! [[String : AnyObject]])
if ((dict!["results"]!.isKindOfClass(NSNull.classForCoder()))) {
//@TODO: Put payment template parameters in function call
self.oauthswift.client.post(self.baseURL + "/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
default:
break
}
},
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?) {
/* 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)
}*/
if(request.containsString("listings/") && request.containsString("/images")){
let url = NSURL(string: self.baseURL + request)!
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-dataheader"]) // 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 body1 = NSMutableData()
let fname = "main.jpg"
let mimetype = "image/jpg"
//define the data post parameter
body1.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body1.appendData("Content-Disposition:form-data; name=\"listing_id\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body1.appendData("\(body["listing_id"] as! Int)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body1.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body1.appendData("Content-Disposition:form-data; name=\"image\"; filename=\"\(fname)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body1.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body1.appendData((body["image"] as! NSData))
body1.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body1.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
requested.HTTPBody = body1*/
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 "/shipping/templates":
break
case "/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 "/shipping/templates":
break
case "/listings":
print(error.userInfo["Response-Body"])
if((error.userInfo["Response-Body"]!.isEqualToString("price is below listing fee."))) {
//@TODO: add alert to let user know that the price they have given is too low for etsy
}
break
default:
break
}
}
)
}
}
}
//MARK: - JSON Methods
extension EtsyRESTAPIManager {
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
}
}