2

I am really new to Swift and I'm trying to make a http request to a URL with consumer key and consumer secret and honestly I'm not sure that is even possible to do in Swift.

I've been trying to make this work with authentication method but it only gives me an error.

My code (Hope this helps you to understand what I'm trying to do..)

let baseUrl = "my url"
let consumer_key = "consumer_key"
let consumer_secret = "consumer_secret"

let loginString = NSString(format:"%@:%@", consumer_key, consumer_secret)
let loginData = loginString.data(using: String.Encoding.utf8.rawValue)!
let base64LoginString = loginData.base64EncodedString()

let url = URL(string: baseUrl)
var request = URLRequest(url: url!)
request.httpMethod = "GET"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")

let config = URLSessionConfiguration.default
let authString = "Basic \(base64LoginString)"
config.httpAdditionalHeaders = ["Authorization" : authString]
let session = URLSession(configuration: config)

 session.dataTask(with: url!) {
     (data, response, error) in
     if (response as? HTTPURLResponse) != nil {
        print("in session")
        let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
        print("data please...",dataString!)
      }
  }.resume()

If this http call with consumer key and consumer secret is totally unacceptable in Swift or if there is any other way that I can get by this, please let me know.

Thank you in advanced.

EDIT------------------------------------------------------

import UIKit


class OrdersViewController: UIViewController {


    @IBOutlet weak var orderView: UITableView!

    var orderData = [[String: AnyObject]]()
    var selectedIndex = -1

    override func viewDidLoad() {
        super.viewDidLoad()
        print("in")
        // Do any additional setup after loading the view.
        let baseUrl = "my url"
        let consumer_key = "consumer_key"
        let consumer_secret = "consumer_secret"

        let loginString = NSString(format:"%@:%@", consumer_key, consumer_secret)
        let loginData = loginString.data(using: String.Encoding.utf8.rawValue)!
        let base64LoginString = loginData.base64EncodedString()

        let url = URL(string: baseUrl)
        var request = URLRequest(url: url!)
        request.httpMethod = "GET"
        request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")

        let config = URLSessionConfiguration.default
        let authString = "Basic \(base64LoginString)"
        config.httpAdditionalHeaders = ["Authorization" : authString]
        let session = URLSession(configuration: config)

        session.dataTask(with: url!) {
            (data, response, error) in
            if (response as? HTTPURLResponse) != nil {
                print("in session")
                let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                print("data please...",dataString!)
            }
        }.resume()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return orderData.count
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if (selectedIndex == indexPath.row) {
            return 100
        } else {
            return 40
        }
    }

    func tableView(tableView: UITableView, cellforRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "Cell"
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! orderCell

        let obj = orderData[indexPath.row]
        print("obj", obj)

        return cell
    }

}
ckim16
  • 1,569
  • 3
  • 19
  • 30
  • Your code looks fine as far as the code goes. The authentication mechanism itself might depend on the server your are accessing. But are you seeing any errors or did you just want to verify that your code follows acceptable coding guidelines? – Fahim Mar 24 '17 at 00:48
  • I don't think it does not run session.dataTask because I don't see my "in session" and "data please..." in my window. I see some error like "unrecognized selector sent to instance 0x7fecb1800490" and "App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file." lastly "terminating with uncaught exception of type NSException" – ckim16 Mar 24 '17 at 05:36

2 Answers2

1

Based on your response, it looks as if you are running into ATS issues - the network code does not run at all since the URL is an http:// URL and not an https:// one.

If you have a secure URL with https:// I would suggest you use it. Otherwise, you can add an ATS exception as detailed in the following SO thread: Transport security has blocked a cleartext HTTP

Community
  • 1
  • 1
Fahim
  • 3,466
  • 1
  • 12
  • 18
  • Thank you for comment. But it still does not work though I added ATS in my plist. I even try with using https:// for domain but same result. – ckim16 Mar 24 '17 at 06:12
  • What is the error you get after you add ATS? If ATS is added correctly (as per the SO thread I linked to) you should not see the "App Transport Security has blocked a cleartext HTTP" error message. If you still see that message, then an ATS exception might not be set up correctly. – Fahim Mar 24 '17 at 06:14
  • I don't see an error like "App Transport Security has blocked a cleartext HTTP" but I see errors such as "unrecognized selector sent to instance 0x7fbc5840b050", "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '" and it shows some First throw call stack and "libc++abi.dylib: terminating with uncaught exception of type NSException" at last. So I'm guessing my domain is fine but the way I'm using NS syntax is wrong? – ckim16 Mar 24 '17 at 16:41
  • Sorry, edit my errort, one of the error says, "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7fc35f401810'. Hope this helps you to understand better. Thank you. – ckim16 Mar 24 '17 at 17:48
  • Can you post the contents of the `numberOfRowsInSection` method? Perhaps taking a look at the code might help me tell you what is going on. Otherwise, I might need to actually run the code to see what the issue is ... – Fahim Mar 25 '17 at 00:07
  • Sorry for the late response, and I posted my code to help you guys understanding better my code. I need to make an http request to url and push those data into my array but I will worry about that later. Please help me what I need to do to make my http request work. Thanks! – ckim16 Mar 27 '17 at 18:14
  • You have an `orderData` variable defined at the top of your code. But you don't seem to actually set the data anywhere after you complete your session. Do you see the "data please ..." message in your console indicating that you actually got data back from your request to the server? – Fahim Mar 28 '17 at 00:05
0

I figured this out by changing my URLsession function.

session.dataTask(with: url!, completionHandler: {
        (data, response, error) in
            if (error != nil) {
                print("in session error", error.debugDescription)
            } else {
                do {
                    print("in session")
                    self.orderData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
                    OperationQueue.main.addOperation {
                        self.orderView.reloadData()
                        print("data", self.orderData)
                    }
                } catch let error as NSError {
                    print(error)
                }
            }
        }).resume()

Now I see "in session" in my console which means it making http call properly but I'm facing a new problem which it says Cannot assign value of type 'NSDictionary' to type '[[String: AnyObect]]'. But I'm still happy that my http call works and finally I can start banging my head to a different problem. Thank you all for helping and I hope this answer can help others as well.

ckim16
  • 1,569
  • 3
  • 19
  • 30