CURL to URLRequest in Swift. (MUX LIVE STREAMING API) - json

Hello I am trying to create a live stream with mux api with a post request in my swift app.
This is what the cURL looks like. The MUX TOKEN ID & SECRET ID are defined in my app in swift:
curl https://api.mux.com/video/v1/live-streams \
-H "Content-Type: application/json" \
-X POST \
-d '{ "playback_policy": "public", "new_asset_settings": { "playback_policy": "public" } }' \
-u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET}
This is my code in swift:
func getStreamKeys() {
let url = URL(string: "https://api.mux.com/video/v1/live-streams")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let parameters: [String: Any] = [
"playback_policy": "public",
"new_asset_settings": ["playback_policy": "public"]
]
request.httpBody = parameters.percentEncoded()
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data,
let response = response as? HTTPURLResponse,
error == nil else { // check for fundamental networking error
print("error", error ?? "Unknown error")
return
}
guard (200 ... 299) ~= response.statusCode else { // check for http errors
print("statusCode should be 2xx, but is \(response.statusCode)")
print("response = \(response)")
return
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
}
task.resume()
}
This is the response I get:
response = <NSHTTPURLResponse: 0x281c928e0> { URL: https://api.mux.com/video/v1/live-streams } { Status Code: 401, Headers {
"Cache-Control" = (
"max-age=0, private, must-revalidate"
);
"Content-Length" = (
69
);
"Content-Type" = (
"application/json; charset=utf-8"
);
Date = (
"Tue, 03 Mar 2020 22:34:45 GMT"
);
Server = (
"Mux API Server v1.89.12"
);
"x-request-id" = (
"FfjsHsz4jsEe_3oAcmYi"
);
} }
This is how the response should be:
{
"data": {
"id": "QrikEQpEXp3RvklQSHyHSYOakQkXlRId",
"stream_key": "super-secret-stream-key",
"status": "idle",
"playback_ids": [
{
"policy": "public",
"id": "OJxPwQuByldIr02VfoXDdX6Ynl01MTgC8w02"
}
],
"created_at": "1527110899"
}
}
I still need to pass -u ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET} the id and secret are constant and should be defined in the getStreamKeys. If someone can help me with it. Thanks

You'll need to add the auth to the api call as described below.
I also replaced your percentEncoded() with JSONSerialization as I do not know what you have in there.
let MUX_TOKEN_ID: String = ""
let MUX_TOKEN_SECRET: String = ""
func getStreamKeys() {
let url = URL(string: "https://api.mux.com/video/v1/live-streams")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let auth = "\(MUX_TOKEN_ID):\(MUX_TOKEN_SECRET)" // create string
let base64Auth = Data(auth.utf8).base64EncodedString() // base64encode the string
request.setValue("Basic \(base64Auth)", forHTTPHeaderField: "Authorization") // add auth to headers
request.httpMethod = "POST"
let parameters: [String: Any] = [
"playback_policy": "public",
"new_asset_settings": ["playback_policy": "public"]
]
do {
let jsonData = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
request.httpBody = jsonData
print(jsonData)
} catch let e {
print(e)
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data,
let response = response as? HTTPURLResponse,
error == nil else { // check for fundamental networking error
print("error", error ?? "Unknown error")
return
}
print(response)
guard (200 ... 299) ~= response.statusCode else { // check for http errors
print("statusCode should be 2xx, but is \(response.statusCode)")
print("response = \(response)")
return
}
let responseString = String(data: data, encoding: .utf8)
}
task.resume()
}

So the -u flag on curl encodes the value as base64 and passes it as the header
Authorization: Basic <some base64 string>
So in Swift, you'd have to encode the values of ${MUX_TOKEN_ID}:${MUX_TOKEN_SECRET} then pass it into the header dictionary.
Example:
let authString = "\(MUX_TOKEN_ID):\(MUX_TOKEN_SECRET)"
let encodedAuthString = Data(authString).base64EncodedString()
request.setValue("Basic \(encodedAuthString)", forHTTPHeaderField: "Authorization")

Related

How can I send swift json to django server?

Swift code:
static func send(url: URL, data: Data) async {
var request = URLRequest(url: url)
request.httpMethod = "POST"
let json: [String: Any] = [
"order_details": ["meal_id":"6", "quantity":"1"],
"restaurant_id": "1",
"access_token": "FUJMNpU77OyuLiohOl5wzRQkGpHleV",
"address": "13"
]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
request.httpBody = jsonData
print(String(data: jsonData ?? Data(), encoding: .utf8))
do {
let (_, response) = try await URLSession.shared.data(for: request)
guard let statusCode = (response as? HTTPURLResponse)?.statusCode, 200..<300 ~= statusCode else {
throw URLError(.badURL)
}
} catch {
print(error)
}
}
Print:
Optional("{\"address\":\"13\",\"order_details\":{\"quantity\":\"1\",\"meal_id\":\"6\"},\"restaurant_id\":\"1\",\"access_token\":\"FUJMNpU77OyuLiohOl5wzRQkGpHleV\"}")
JSON looks normal.
BUT in my django server I get this:
if request.method == "POST":
print(request.POST)
Print:
<QueryDict: {'{"address":"13","order_details":{"quantity":"1","meal_id":"6"},"restaurant_id":"1","access_token":"FUJMNpU77OyuLiohOl5wzRQkGpHleV"}': ['']}>
i.e. my request becomes a key
I tried to compose the request in different ways, I used JSONEncoder and JSONSerializer but nothing happened

how to make HTTPRequest with json in swift

I am making an ios application. I am new to swift and not able to understand my code. can anyone please help me to understand what is going on with my code.
This is login application on adding email id if the email exist it should go to next view controller and if not then it should give error. I am getting difficulty in understanding my code .
Here is my code:
class checkLoginViewController: UIViewController {
#IBOutlet weak var checkUsernametextfield: UITextField!
#IBAction func checkUsernameButton(_ sender: UIButton) {
print("Clicked On SUbmit !!!!")
//Read Value from Text
let email = checkUsernametextfield.text
let myUrl = URL(string: "http://192.168.0.117/rest/signup.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
let postString = "email=\(String(describing: email))";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil
{
print("error=\(String(describing: error))")
return
}
// You can print out response object
print("response = \(String(describing: response))")
//Let's convert response sent from a server side script to a NSDictionary object:
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
// Now we can access value of First Name by its key
let emailValue = parseJSON["email"] as? String
print("email: \(String(describing: emailValue))")
}
} catch {
print(error)
}
}
task.resume()
Output:
Clicked On SUbmit !!!! response = Optional( { URL: http://192.168.0.117/rest/signup.php } { Status
Code: 200, Headers {
Connection = (
"Keep-Alive"
);
"Content-Length" = (
61
);
"Content-Type" = (
"application/json"
);
Date = (
"Mon, 12 Mar 2018 06:35:58 GMT"
);
"Keep-Alive" = (
"timeout=5, max=100"
);
Server = (
"Apache/2.4.27 (Ubuntu)"
); } }) email: nil
Maybe try this. Hope it works.
let url = URL(string:"http://192.168.0.117/rest/signup.php")
let parameters = ["email": checkUsernametextfield.text]
var request = URLRequest(url : url!)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject:parameters, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
session.dataTask(with: request, completionHandler: { (data, response, error) in
if let data = data {
do {
let json = try? JSONSerialization.jsonObject(with: data, options: []) as! Dictionary<String, Any>
if let json = json {
print("HERE SHOULD BE YOUR JSON \(json)")
}
}
} else {
print("Error \(String(describing: error?.localizedDescription))")
}
}).resume()
Here is way to send request.
enter code here
static func downloadConfig(url:URL, completion:#escaping (_ sucess:Bool , _ jsonObject: [String: String]?)->() ) {
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded",
forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "id=13&name=Jack"
request.httpBody = postString.data(using: .utf8)
URLSession.shared.dataTask(with: request) { (data,response,error) in
if let data = data ,let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200 {
do {
if let todoJSON = try JSONSerialization.jsonObject(with: data, options: []) as? [String: String]{
completion(true,todoJSON)
}
else
{
completion(false,nil)
}
}
catch {
//erro parsing
completion(false,nil)
}
}
else
{
completion(false,nil)
}
}.resume()
}
use this download json function in this way.
//Download Json File
let base_url = "base_url"
let urlstr = String.init(format: "%#", base_url)
let url = URL(string: urlstr)
GameUtil.downloadConfig(url: url!) {
(sucess: Bool , jsonObject: [String:String]?) in
if sucess , jsonObject != nil
{
self.configJson = jsonObject!
}
}

How to send a POST request through Swift?

I have my controller like this -
def create
if (#user = User.find_by_email(params[:email])) && #user.valid_password?(params[:password])
render json: #user.as_json(only: [:email,:authentication_token]),status: :created
else
render json:('Unauthorized Access')
end
end
When I use Postman to make this request, I choose Body, and form data and adds in the email and password. And this WORKS
How to use swift to do the same? This is what I have tried
let url = URL(string: "http://localhost:3000/api/v1/user_serialized/")
let config = URLSessionConfiguration.default
let request = NSMutableURLRequest(url: url!)
request.httpMethod = "POST"
let bodyData = "email=Test#test.com&password=Test1234"
request.httpBody = bodyData.data(using: String.Encoding.utf8);
let session = URLSession(configuration: config)
let task = session.dataTask(with: url! as URL, completionHandler: {(data, response, error) in
let json = JSON(data:data!)
debugPrint(json)
})
task.resume()
I have made a Custom HTTP class where we can sent url, parameter and we will get Data from API. Below is the class.
import Foundation
//HTTP Methods
enum HttpMethod : String {
case GET
case POST
case DELETE
case PUT
}
class HttpClientApi: NSObject{
//TODO: remove app transport security arbitary constant from info.plist file once we get API's
var request : URLRequest?
var session : URLSession?
static func instance() -> HttpClientApi{
return HttpClientApi()
}
func makeAPICall(url: String,params: Dictionary<String, Any>?, method: HttpMethod, success:#escaping ( Data? ,HTTPURLResponse? , NSError? ) -> Void, failure: #escaping ( Data? ,HTTPURLResponse? , NSError? )-> Void) {
request = URLRequest(url: URL(string: url)!)
logging.print("URL = \(url)")
if let params = params {
let jsonData = try? JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request?.setValue("application/json", forHTTPHeaderField: "Content-Type")
request?.httpBody = jsonData//?.base64EncodedData()
//paramString.data(using: String.Encoding.utf8)
}
request?.httpMethod = method.rawValue
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
configuration.timeoutIntervalForResource = 30
session = URLSession(configuration: configuration)
//session?.configuration.timeoutIntervalForResource = 5
//session?.configuration.timeoutIntervalForRequest = 5
session?.dataTask(with: request! as URLRequest) { (data, response, error) -> Void in
if let data = data {
if let response = response as? HTTPURLResponse, 200...299 ~= response.statusCode {
success(data , response , error as? NSError)
} else {
failure(data , response as? HTTPURLResponse, error as? NSError)
}
}else {
failure(data , response as? HTTPURLResponse, error as? NSError)
}
}.resume()
}
}
Now you can refer below code to get how to make an API call.
var paramsDictionary = [String:Any]()
paramsDictionary["username"] = "BBB"
paramsDictionary["password"] = "refef"
HttpClientApi.instance().makeAPICall(url: "Your URL", params:paramsDictionary, method: .POST, success: { (data, response, error) in
// API call is Successfull
}, failure: { (data, response, error) in
// API call Failure
})
I think you should pass your request instead of the url to session.dataTask
here is how my code looks like:
private let url = URL(string: "http://example.com/")!
func httpPost(jsonData: Data) {
if !jsonData.isEmpty {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = jsonData
URLSession.shared.getAllTasks { (openTasks: [URLSessionTask]) in
NSLog("open tasks: \(openTasks)")
}
let task = URLSession.shared.dataTask(with: request, completionHandler: { (responseData: Data?, response: URLResponse?, error: Error?) in
NSLog("\(response)")
})
task.resume()
}
}
Here is the Example of POST API for calling Login API with parameters "emailaddress" and "password" with userEmailID and Userpassword as two strings holding values for email and password respectively.
You can call this POST API anywhere in your view controller, as given below:
self.postLoginCall(url: "Your post method url") example: self.postLoginCall(url: "http://1.0.0.1/api/login.php")
func postLoginCall(url : String){
let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
request.httpMethod = "POST"
let postString = "emailaddress=\(userEmailID!)&password=\(Userpassword!)"
print(postString)
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
do {
if let responseJSON = try JSONSerialization.jsonObject(with: data!) as? [String:AnyObject]{
print(responseJSON)
print(responseJSON["status"]!)
self.response1 = responseJSON["status"]! as! Int
print(self.response1)
//Check response from the sever
if self.response1 == 200
{
OperationQueue.main.addOperation {
//API call Successful and can perform other operatios
print("Login Successful")
}
}
else
{
OperationQueue.main.addOperation {
//API call failed and perform other operations
print("Login Failed")
}
}
}
}
catch {
print("Error -> \(error)")
}
}
task.resume()
}
Hello everyone I share below an example of a function to make a request in POST with SWIFT 5+.
This function allows you to send a POST request with an API entry point and parameters in the form of [[String: String]] and an Int to determine the output action.
For the output actions we call a function with Switch Case.
The operation is extremely simple. You have to put the two functions in one of your classes.
func MGSetRequestApi(endpoint: String, parameters: [[String: String]], MGSetAction: Int) -> String {
var setReturn: String!
let semaphore = DispatchSemaphore (value: 0)
var MGGetParam: String! = ""
for gate in parameters {
for (key, value) in gate {
let myParam = key + "=" + value + "&"
MGGetParam.append(contentsOf: myParam)
}
}
let postData = MGGetParam.data(using: .utf8)
var request = URLRequest(url: URL(string: endpoint)!,timeoutInterval: 10000)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
semaphore.signal()
return
}
print(String(data: data, encoding: .utf8)!)
setReturn = String(data: data, encoding: .utf8)!
DispatchQueue.main.async {
self.MGRequestAction(MGGetIdRq: MGSetAction, MGGetData: setReturn)
}
semaphore.signal()
}
task.resume()
semaphore.wait()
return setReturn
}
Then implement this function to manage the outputs
func MGRequestAction(MGGetIdRq: Int, MGGetData: String) {
switch MGGetIdRq {
case 1:
// Do something here
case 2:
// Do something else here
case 3:
// Do something else here again
default:
print("Set default action");
}
}
How to use this, you have two possibilities, the first one is to process what the function
MGSetRequestApi(endpoint: String, parameters: [[String: String]], MGSetAction: Int) -> String
returns (String) or to pass by the function
MGRequestAction(MGGetIdRq: Int, MGGetData: String)
which will call your Json parse function.
The MGRequestAction() function takes for parameter an Int for the choice of the action and the String of the return of the request
Now to use it do like this:
_ = MGSetRequestApi(endpoint: MY_END_POINT_API,
parameters: [["KEY_1": "VALUE 1"],
["KEY_2": "VALUE 2"],
["KEY_3": "VALUE 3"],
["KEY_4": "VALUE 4"]],
MGSetAction: 3)

AlamoFire Request Google Cloud Prediction API iOS Parse Error

I am using AlamoFire to make POST queries to one of my models in Google Cloud Prediction. Whenever I send a request, I get back an error stating: This API does not support parsing form-encoded input.
After a bit of researching, I found that I needed to set my Content-Type HTTP header to "application/json". Hopefully, you can find something that I missed when making my request. Here is my code:
let parameters = [
"access_token" : accessToken,
"input": [
"csvInstance": [
"This is very positive"
]
]
]
Alamofire.Manager.sharedInstance.session.configuration
.HTTPAdditionalHeaders?.updateValue("application/json",
forKey: "Accept")
Alamofire.Manager.sharedInstance.session.configuration
.HTTPAdditionalHeaders?.updateValue("application/json",
forKey: "Content-Type")
Alamofire.request(.POST, "https://www.googleapis.com/prediction/v1.6/projects/mailanalysis-1378/trainedmodels/10kTweetData/predict", parameters: parameters).responseJSON { (response) in
if let JSON = response.result.value {
print("JSON: \(JSON)")
//print("refresh token = " + auth.accessToken)
}
}
In case someone is still looking for an answer, I managed to access GooglePredictionAPI from my iOS client without Alamofire:
var accessToken: String?
GIDSignIn.sharedInstance().currentUser.authentication.getTokensWithHandler { (authentication, error) in
if let err = error {
print(err)
} else {
if let auth = authentication {
accessToken = auth.accessToken
}
}
}
if let accTok = accessToken {
let parameters = [
"input": [
"csvInstance": [
0.9,
0.14,
-0.41,
1.61,
-1.67,
1.57,
-0.14,
1.15,
0.26,
-1.52,
-1.57,
3.65
]
]
]
let url = NSURL(string: "https://www.googleapis.com/prediction/v1.6/projects/ExermotePredictionAPI/trainedmodels/getExercise/predict")
let session = URLSession.shared
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST" //set http method as POST
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("Bearer \(accTok)", forHTTPHeaderField: "Authorization")
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: AnyObject] {
print(json)
}
} catch let error {
print(error.localizedDescription)
}
})
task.resume()
}

How to POST JSON data using NSURLSession in swift

I am stuck with the below code. How do I set the param and in post method?
let params:[String:Any] = [
"email" : usr,
"userPwd" : pwdCode]
let url = NSURL(string:"http://inspect.dev.cbre.eu/SyncServices/api/jobmanagement/PlusContactAuthentication")
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPBody = params<what should do for Json parameter>
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
println("response was not 200: \(response)")
return
}
}
if error {
println("error submitting request: \(error)")
return
}
// handle the data of the successful response here
}
task.resume()
if I understand the question correctly
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
var session = NSURLSession(configuration: configuration)
var usr = "dsdd"
var pwdCode = "dsds"
let params:[String: AnyObject] = [
"email" : usr,
"userPwd" : pwdCode ]
let url = NSURL(string:"http://localhost:8300")
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.allZeros, error: &err)
let task = session.dataTaskWithRequest(request) {
data, response, error in
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
println("response was not 200: \(response)")
return
}
}
if (error != nil) {
println("error submitting request: \(error)")
return
}
// handle the data of the successful response here
var result = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil) as? NSDictionary
println(result)
}
task.resume()
I would suggest using AFNetworking. See for example, Posting JSON data using AFNetworking 2.0.
This is how you can set parameters and send a POST request, easy approach using Alamofire.
Swift 2.2
let URL = NSURL(string: "https://SOME_URL/web.send.json")!
let mutableURLRequest = NSMutableURLRequest(URL: URL)
mutableURLRequest.HTTPMethod = "POST"
let parameters = ["api_key": "______", "email_details": ["fromname": "______", "subject": "this is test email subject", "from": "support#apple.com", "content": "<p> hi, this is a test email sent via Pepipost JSON API.</p>"], "recipients": ["_________"]]
do {
mutableURLRequest.HTTPBody = try NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions())
} catch {
// No-op
}
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
Alamofire.request(mutableURLRequest)
.responseJSON { response in
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}