Receiving projects list using JIRA API - ios

I want make simple JIRA assistant for iOS but cannot figure out why API call return empty array.
For example, using this code i'm trying to get projects list:
let request = NSMutableURLRequest(URL: "http://myjira.atlassian.net/rest/api/2/project".URL!)
request.addValue("Basic " + emailAndPasswordAsb64String, forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "GET"
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request) { (data, response, error) -> Void in
guard let data = data, responseString = NSString(data: data, encoding: NSUTF8StringEncoding) as? String where !responseString.isEmpty else {
print("No valid response!", appendNewline: true)
return
}
print("Response: " + responseString, appendNewline: true)
}.resume()
But getting this: Response: []
I'm also tried to use some other API, for example api/2/dashboard, but received this:
Response: {"startAt":0,"maxResults":20,"total":0,"dashboards":[]}
Using api/2/myself i received this:
Response: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><status><status-code>401</status-code><message>Client must be authenticated to access this resource.</message></status>
Maybe i missed something and project can be invisible? But for basic authorization i'm using administrator login and password.

Finally figured it out!
I did two mistakes:
http is wrong, https is right!
emailAndPasswordAsb64String was created using email and password, it's wrong! User should type in username instead of email! For administrator account username is admin by default.
Hope this will help someone!

Related

What is the best way to add data and upload files to Rest api

My iOS application allows a user to submit a complaint to an online REST API with the following parameters:
Data Fields: such as name, phone number, ...
Voice: recorded from microphone
Image/Video: selected from photo gallery
1- how can i do that with swift?
2- how to get back an ID field from the server after submission?
3- how to manage an upload progress for the voice and media files?
Regards
After few weeks working hardly on it, here is my experience using Swift 3.1 which is run smoothly:
//use POSTMAN plugin in Chrome browser to get the read header for your API (optional):
let headers = [
"cache-control": "no-cache",
"postman-token": "00000000-1111-2222-3333-444444444"]
//this is the important part:
let strQuery: String = "mobileNo=" + txtMobileNB.text! + "&fullname=" + txtName.text!
let request = try? NSMutableURLRequest(url: NSURL(string: "http://service.website.com/apiname/?" + strQuery)! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request?.httpMethod = "POST"
request?.allHTTPHeaderFields = headers
if request != nil {
let session = URLSession.shared
let dataTask = session.dataTask(with: request! as URLRequest) {data,response,error in
if let content = data
{
let responseData = String(data: content, encoding: String.Encoding.utf8)
//feedback from server:
print(responseData)
//call success function:
self.showDone()
} else {
//call error function:
self.showWrong()
}
}
dataTask.resume()
} else {
//call error function:
self.showWrong()
}
Regarding the other part "how to upload", i've found this framework is a good one (called rebekka) to start your upload project through iOS apps.
hope this helps someone :)

How to get a MS Translator access token from Swift 3?

I am trying to work with a MS Translator API from Swift 3 (right now playing in playgrounds, but the target platform is iOS). However, I got stuck when I was trying to get an access token for OAuth2. I have following code (I tried to port the code from example at Obtaining an access token):
let clientId = "id".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let clientSecret = "secret".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let scope = "http://api.microsofttranslator.com".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let translatorAccessURI = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13"
let requestDetails = "grant_type=client_credentials&client_id=\(clientId)&client_secret=\(clientSecret)&scope=\(scope)"
let postData = requestDetails.data(using: .ascii)!
let postLength = postData.count
var request = URLRequest(url: URL(string: translatorAccessURI)!)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("\(postLength)", forHTTPHeaderField: "Content-Length")
request.httpBody = postData
URLSession.shared.dataTask(with: webRequest) { (returnedData, response, error) in
let data = String(data: returnedData!, encoding: .ascii)
print(data)
print("**************")
print(response)
print("**************")
print(error)
}.resume()
Of course, I used a valid clientId and a valid clientSecret.
Now the callback prints following information. First, the returnedData contain a message that the request was invalid, along with a following message:
"ACS90004: The request is not properly formatted."
Second, the response comes with a 400 code (which fits the fact that the request is not properly formatted).
Third, the error is nil.
Now I was testing the call using Postman, and when I used the same URI, and put the requestDetails string as a raw body message (I added the Content-Type header manually), I got the same response. However, when I changed the body type in Postman UI to application/x-www-form-urlencoded and typed in the request details as key value pairs through its UI, the call succeeded. Now it seems that I am doing something wrong with the message formatting, or maybe even something bad with the Swift URLRequest/URLSession API, however, I cannot get a hold on to what. Can somebody help me out, please? Thanks.
OK, so after some more desperate googling and experimenting I have found my error. For the future generations:
The problem resided in encoding the parameters in the body of the PUT http request. Instead of:
let scope = "http://api.microsofttranslator.com"
.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
I have to use the following:
let scope = "http://api.microsofttranslator.com"
.addingPercentEncoding(withAllowedCharacters:
CharacterSet(charactersIn: ";/?:#&=$+{}<>,").inverted)!
Seems that the API (or the HTTP protocol, I am not an expert in this) have problems with / and : characters in the request body. I have to give credit to Studiosus' answer on Polyglot issue report.

iOS facebook login without SDK http post Swift/Obj-C

Let me start off by saying the purpose of this code is so I can practice on various other sites with login pages or forms. This is why I do no wish to use Facebook's SDK. So please...
Do not point me to Facebook's SDK (many other questions specifically asking for without SDK have been given SDK answers)
Ideally I would like to create an app that has preset information that will login to a site (such as Facebook) when the app opens or a button is pressed
I'd prefer an answer in Swift but I can read Objective - C and may be able to decipher it
Here is some sample code I've tried:
let myURL = NSURL(string: "https://mobile.facebook.com")
let request = NSMutableURLRequest(URL: myURL!)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-type")
let postString = "email=*email&pass=*pass&login=Log In"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let postInt = postString.characters.count
request.setValue("\(postInt)", forHTTPHeaderField: "Content-length")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
}
if let HTTPResponse = response as? NSHTTPURLResponse {
let sCode = HTTPResponse.statusCode
if sCode == 200 {
// Then do something.
self.webView.loadRequest(request)
}
}
print("respone = \(response)")
}
task.resume()
*email = The user's email
*pass = The user's password
note: email, pass, Log In were taken from the form name values on the html code.
Current results- I am able to get the email to appear on opening of the app but the password is blank and it doesn't appear to have attempted a log in.
Please help and let me know if you need any clarifications
PS I've been looking for about a week now to no avail so I apologize if the answer is somewhere. I am not completely familiar with terminology to look for it.

NSURLSession.sharedSession().dataTaskWithRequest(request) not returning anything unless there is an error

Why aren't any results being printed?
I have been searching all over for an answer. I've tried many different example blocks of code. The print statements never fires unless an error is produced. For example: If I change the URL to "http" only with nothing else, I naturally get an error and it prints the error. However, any valid URL produces no result in the print statement.
func post()
{
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.thebeerstore.ca")!)
request.HTTPMethod = "POST"
let postString = "experiment"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString!)")
}
task.resume()
}
Edit: It works if I use a playground, but only in a playground.
In your application's Info.plist file, add the property App Transport Security Settings and under that, add Allow Arbitrary Loads and assign YES for it.
With the above settings in your Info.plist, the app should be able to load your http:// URLs as well
Note: I would recommend not to use the above settings in your
production build, it could result in security issues.
There is no good explanation for this, but having finally stuck this same problem code into my primary project, it now works perfectly ok. What changed??? Arrrrg! How many hours wasted and I still don't really know why it wasn't working outside of my primary app. Thanks for your help everyone.
Final code:
I do hope I can send over 100MB through a post request to be interpreted on the server side and store to the database. Haven't done this before. I'm a newbie.
func post()
{
let request = NSMutableURLRequest(URL: NSURL(string: "http://bruceexpress.com/database.php")!)
request.HTTPMethod = "POST"
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(stores, options: [])
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString!)")
}
task.resume()
}
Edit: Yes, you can post a huge block of data. Is this the correct way to do it? ( Forgive my silly questions, but I am recovering programming skills left over from 2001. I am a very outdated individual. )
Basically, what I have done is read all of the data on http://www.thebeerstore.ca, extracted every beer and its info and prices, and extracted every store and its info. I interpreted this data, converted it into a large JSON block, and sent it to my server to be interpreted by a php script which will store this data to a database.
Sound like the right thing to do, or is there a better way to fill the database?

Send body in PUT request in swift

I tried to send body in PUT request but the data is not received on backend
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "PUT"
let putBody = "bucket=\(bucket)&day=\(day)"
request.HTTPBody = putBody.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {(data, response, error) -> Void in
dispatch_async(dispatch_get_main_queue(), {() -> Void in
completion(data: data, response: response as! NSHTTPURLResponse, error: error)
})
})
task.resume()
The value of bucket (Int) is 2015040 and day (String) is day27. I tried making same request in Postman, the server received body data so there is nothing wrong with the server.
Is there any other way to set body of a request?
EDIT :
It's working perfectly if I change request method to POST in my request and server as well. So the question comes down to how to set body in PUT request?
I've just been dealing with this. Had the exact same issue where it was working perfectly fine with POST but not with PUT or PATCH requests. It seems that for PUT and PATCH requests, Swift is picky about the Content-Type header.
So try adding this:
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
This will work as long as your body is url style, so like this:
key=value&key=value&key=value
For those of you using JSON, just use application/json instead for the Content-Type.

Resources