I use Octkit for the first time and I used cocoapods to install it, but it does not work as it was explained in the GitHub: https://github.com/nerdishbynature/octokit.swift
So I tried to implement code this way;
let token = GithubAPIManager.sharedInstance.OAuthToken
let config = TokenConfiguration(token)
Octokit(config).me() { response in
switch response {
case .Success(let user):
case .Failure(let error):
}
}
But when I add TokenConfiguration there is an error saying
use of unresolved identifier
And also for the Octkit(config) there is an error. I imported Octokit and Foundation. What is wrong?
Solution is quite simple (had the same issue): in the example the reference to the enum is incorrect, additionally println isn't available in Swift 3 anymore.
.success and .failure need to be lowercase. If you want to print like the example in the readme file use print instead of println.
let token = GithubAPIManager.sharedInstance.OAuthToken
let config = TokenConfiguration(token)
Octokit(config).me() { response in
switch response {
case .success(let user):
case .failure(let error):
}
}
Related
I am studying networking (Alamofire).
And in his pet project on Viper architecture.
I am making a get request and getting a to-do list from a local server.
The data is returned to me successfully.
But I just can't figure out how to get them and transfer them to Interactor...
I want my fetchToDos method to return an array. But I keep making mistakes.
func fetchToDos() -> [ToDo]? { // <- My mistake is clearly here
let request = Session.default.request("http://localhost:3003/")
request.responseDecodable(of: ToDos.self) { (response) in
switch response.result {
case .success(let tasks):
print("SUCCESS to FETCH JSON: \(tasks)")
case .failure(let error):
print("FAILED to FETCH JSON: \(error.localizedDescription)")
}
}
}
you are using an asynchronous function, and so one way to get something out
of it when it is finished, is to use a completion handler, something like this:
(note you need to do the error checking etc...before you can use this for real)
class ToDoNetworking {
func fetchToDos(completion: #escaping ([ToDo] -> Void)) { // <- try this
let request = Session.default.request("http://localhost:3003/")
request.responseDecodable(of: [ToDos].self) { (response) in
switch response.result {
case .success(let tasks):
print("SUCCESS to FETCH JSON: \(tasks)")
completion(tasks) // <-- assuming tasks is [ToDo]
case .failure(let error):
print("FAILED to FETCH JSON: \(error.localizedDescription)")
completion([])
}
}
}
}
What is the type of data being returned by the network call? If it's an array of ToDo objects and your ToDo object supports Codable, then it's likely you want:
request.responseDecodable(of: [ToDo].self)
you pass in the type of object that you want to decode, which it sounds like, is an array of ToDo objects, hence [ToDo].self.
I want to update my code in the past when I used swift 2 or 3. I am stuck where I want to use Alamofire but the way to use it changed and I don't know how to use it anymore. Can anybody update this part of the code and explain a little bit? Thank you.
This is the original code.
Alamofire.request(.POST, url)
.response{ (request, response, data, error) in
let xml = SWXMLHash.parse(data!)
let sunsetTime = xml["result"]["rise_and_set"]["sunset_hm"].element?.text
self.sunsetTimeLabel.text = sunsetTime
self.getDateFromString(sunsetTime,year: comp.year,month: comp.month,day: comp.day)
if (error != nil) {
print(error)
}
}
this is the code I was writing.
AF.request(url, method: .post).responseJSON { (responseData) in
let xml = SWXMLHash.parse(responseData as Data)
let sunsetTime = xml["result"]["rise_and_set"]["sunset_hm"].element?.text
self.sunsetTimeLabel.text = sunsetTime
There is an error saying "Cannot convert value of type 'AFDataResponse' (aka 'DataResponse') to type 'Data' in coercion"
Your first code snippet is Alamofire 3 syntax. I infer from the second code snippet that you are now using Alamofire 5.
There are a few issues:
You are calling responseJSON (which you’d only use if your response was JSON, not XML). Use response or, better, responseData.
The response object passed to this closure is not a Data, itself. In the case of responseData method, it is a AFDataResponse object, which has a data property (which is a Data?). You have to extract the Data object from this AFDataResponse, either by unwrapping the contents of the data property, or from the result (see next point).
You should probably check for success or failure and extract the Data from the response.result object.
So, pulling this together, you end up with something like:
AF.request(url, method: .post).responseData { response in
switch response.result {
case .failure(let error):
print(error)
case .success(let data):
let xml = SWXMLHash.parse(data)
...
}
}
I have this code in a ServiceClient. It handles service-level calls, like signIn(user, password, completion), listObjects(completion), addObject(objectID, content, completion), getObject(id, completion) etc. It contains (but doesn't subclass) an APIClient, which performs only basic HTTPS services like perform(request, completion).
I don't really want the controller that sits above this to deal with 404s as success, which means trapping the error in ServiceClient. So the idea is APIClient deals with networking errors whereas ServiceClient deals with unexpected HTTP results.
So I end up with this in ServiceClient, where errors like invalidURL are converted from an APIClient enum to a ServiceClient enum:
apiClient.perform(request) {result in
switch result {
case .success(let data):
guard data.statusCode == 200 else {
completion(.failure(.badResponse))
return
}
completion(.success(data))
case .failure(let error):
switch error {
case .invalidURL:
completion(.failure(.invalidURL))
case .requestFailed:
completion(.failure(.requestFailed))
case .decodingFailure:
completion(.failure(.decodingFailure))
}
}
}
I think in this case I'll just make APIClient handle invalid HTTP status codes, but what's the more general solution to this? At some point I'll want different error codes for different service clients, at which point this becomes a problem again.
I suggest using Int type enumeration for both ServiceClient and APIClient.
As I understood this is your custom enumerations.
So, assuming you have ServiceClientError and APIClientError you can implement them using this way:
enum ServiceClientError: Int {
case invalidURL, requestFailed, decodingFailure
}
enum APIClientError: Int {
case invalidURL, requestFailed, decodingFailure
}
You can create your custom conversion method:
extension ServiceClientError {
static func create(from apiClientError: APIClientError) -> ServiceClientError {
return ServiceClientError(rawValue: apiClientError.rawValue)
}
}
Wanted function:
apiClient.perform(request) {result in
switch result {
case .success(let data):
guard data.statusCode == 200 else {
completion(.failure(.badResponse))
return
}
completion(.success(data))
case .failure(let error):
guard let serviceClientError = ServiceClientError.create(from: error) else {
/// Handle incorrect behavior
fatalError("Wrong enumeration mapping")
return
}
completion(.failure(serviceClientError))
}
}
How do you add listener to your SyncSubscriptions? The code from the documentation doesn’t seem to work:
let results = realm.objects(Person.self).filter("age > 18")
let subscription = results.subscribe()
let subscriptionToken = subscription.observe(\.state) { state in
switch state {
case .creating:
print("creating")
case .pending:
print("pending")
case .complete:
print("complete")
case .invalidated:
print("invalidated")
case .error(let err):
print("err")
}
This code does not execute any of those cases. Am i missing something? TIA
every one,
I'm having an issue with Alamofire 3.0, when I post data, it seems the data is being sent twice.
I looked up on the web, found that a bug about special caratères was fixed, but I still get the error.
Anyone has an idea. I'm using a parameter in the header called X-Authorization.
Here is an extract of the code i'm using:
static func postData (url: String,token: String,params :Dictionary<String,AnyObject>){
print("POSTINGGGGGG")
Alamofire.request(.POST, url, parameters: params,headers: ["X-Authorization": token])
.responseJSON { response in
switch response.result {
case .Success(let data): break
//let resultJSON = JSON(data).dictionaryValue
// print(data)
case .Failure(let error):
print(error)
}
}
}
Thank you in advance,
Morgan