I want to connect to my localhost (homestead with laravel) to test my swift app. Therefore I use Alamofire to send data via my API to be saved in my database. When I connect to my staging server (in the cloud) everything works fine. But when I want to connect to my local machine (192.168.10.10) it doesn't work through the iOS app. Using the same connection via POSTMAN does work fine and I can access everything.
How do I need to configure Alamofire, that I can use my localhost IP to connect to my test database?
import Foundation
import Alamofire
enum Router: URLRequestConvertible {
static let baseURLString = "http://192.168.10.10/v1"
// == AUTHENTICIATION ==
case RegisterUser([String:AnyObject])
// match URLRequest routes to Alamofire methods
var URLRequest: NSMutableURLRequest {
var method: Alamofire.Method {
switch self {
// == AUTHENTICATION RESOURCE ==
case .RegisterUser:
return .POST
}
}
let result: (path: String, parameters: [String: AnyObject]?) = {
switch self {
// == AUTHENTICATION RESOURCE ==
case .RegisterUser(let newUser):
return ("mfusers", newUser)
}()
// Generate URL Request
let URL = NSURL(string: Router.baseURLString)!
// Append the path components from the result
let URLRequest = NSURLRequest(URL: URL.URLByAppendingPathComponent(result.path))
// Create URLRequest inclunding the encoded parameters
var parametersEncoding:Alamofire.ParameterEncoding {
switch method {
case .GET:
return .URL
case .POST, .PUT:
return .JSON
default:
return .JSON
}
}
let encoding = parametersEncoding
let (encodedRequest, _) = encoding.encode(URLRequest, parameters: result.parameters)
encodedRequest.HTTPMethod = method.rawValue
return encodedRequest
}
}
Related
I've been searching the internet and still cannot find an answer.
My app talks to other smart home products within the home. For example, it can make requests to the Philips Hue Bridge to control the lights via POST requests. The IP of my bridge is 192.168.0.12. I am making a POST request to this endpoint, however it isn't allowed as the connection is unsecure.
I still want to keep the setting of where external connections to domains are secure since I connect to my own server via a domain, which is secure. So I only want to allow local connections via local IP addresses to be unsecure.
I have tried this:
Yet it doesn't work. I've even tried using Allow Arbitrary Loads just for testing to see if it would work, and it still wouldn't.
My API call:
func getPhilipsHueUsername(completion: #escaping (String?, Error?) -> Void){
var bridgeIP = UserDefaults.standard.string(forKey: "bridgeIP")
let url = "http://" + bridgeIP! + "/api"
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = HTTPMethod.post.rawValue
let body = [
"devicetype": "test"
]
do {
let dataToS = try JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed)
request.httpBody = dataToS
}catch{
print("Error creating data object")
return
}
AF.request(request).responseJSON { (response) in
switch response.result {
case .success(let value):
print(value)
if(response != nil){
let json = JSON(value)
print(value)
}
return completion("",nil)
case .failure(let error):
return completion(nil, error)
}
}
}
Does Alamofire support variables in a url path, I have looked for an example but i can't find it.
I have looked in their their docs and unit tests.
It is pretty common for apis to be written with url support for the following:
http://someapi.com/users/{user}/profile
I have looked through their examples in URLEncoding, but i cant find nothing that does the above, examples only seem to add query parameters.
Alamofire relies on the Foundation URL struct, so you need to look there.
URLs offer several different mechanisms for constructing them, the one you could be using is path component, for example:
var url = URL(string: "http://someapi.com/users")
let user = "user"
url?.appendPathComponent(user)
url?.appendPathComponent("profile")
Additionally, you could leverage enums to clean up a bit and maybe construct URLs from strings, something like this:
enum MyURLScheme {
case profile(user: String)
var url: URL? {
switch self {
case .profile(let user):
let url = URL(string: "http://someapi.com/users/\(user)/profile")
return url
}
}
}
let profileURL = MyURLScheme.profile(user: "user").url
EDIT: You can also use Alamofire Router class for building requests, taken from here:
enum Router: URLRequestConvertible {
case search(query: String, page: Int)
static let baseURLString = "https://example.com"
static let perPage = 50
// MARK: URLRequestConvertible
func asURLRequest() throws -> URLRequest {
let result: (path: String, parameters: Parameters) = {
switch self {
case let .search(query, page) where page > 0:
return ("/search", ["q": query, "offset": Router.perPage * page])
case let .search(query, _):
return ("/search", ["q": query])
}
}()
let url = try Router.baseURLString.asURL()
let urlRequest = URLRequest(url: url.appendingPathComponent(result.path))
return try URLEncoding.default.encode(urlRequest, with: result.parameters)
}
}
Alamofire.request(Router.search(query: "foo bar", page: 1))
I can't seem a to find a way to create http requests using proxies, let say i have a Sock5 proxy or HTTP Proxy how would i go about creating a GET/POST request via a proxy, without having to apply the proxy to the system.
I only want the single request to go through a proxy.
Let's say i create a http request using Alamofire, then the request would go through my ip address, but what if i want to apply a http proxy or socks5 proxy to send the request through.
Let's say I make a request like that:
Alamofire.request("https://httpbin.org/get").responseJSON { response in
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
How would i apply the http or socks proxy to this request?
Can't seem to find anything about it.
Taken from this thread:
You create proxy details:
struct ProxyItem: Equatable, Hashable {
let host: String
let port: String
let HTTPOnly = true
var hashValue: Int {
return host.hashValue ^ port.hashValue
}
}
then create proxy configuration
var proxyConfiguration = [NSObject: AnyObject]()
proxyConfiguration[kCFNetworkProxiesHTTPProxy] = item.host
proxyConfiguration[kCFNetworkProxiesHTTPPort] = port
proxyConfiguration[kCFNetworkProxiesHTTPEnable] = 1
set the Alamo configuration:
let sessionConfiguration = AFManager.sharedInstance.session.configuration
sessionConfiguration.connectionProxyDictionary = proxyConfiguration
Create an alamo manager from this configuration:
manager = Alamofire.Manager(configuration: sessionConfiguration)
Finally use the manager to connect to your proxy:
manager.request(.GET, urlString)
.response {
(request, response, data, error) in
if let response = response {
var statusCode = response.statusCode
println("-->statusCode: \(statusCode)")
}
if (error == nil) {
var serializationError: NSError?
let jsonData: AnyObject? = NSJSONSerialization.JSONObjectWithData(data! as! NSData, options: NSJSONReadingOptions.AllowFragments, error: &serializationError)
var parser: Parser = Parser()
let menu: Menu = parser.parseMenuJSON(jsonData)
var dataAccess: DataAccess = DataAccess.sharedInstance
dataAccess.addMenu(menu)
} else {
println("Webservice error: \(error)")
}
}
I created a Router to generate URL Requests.
enum Router: URLRequestConvertible {
static let baseURLString = "SERVERIP"
case GetAEDInRange(String)
// match URLRequest routes to Alamofire methods
var URLRequest: NSMutableURLRequest {
var method: Alamofire.Method {
switch self {
case .GetAEDInRange:
return .GET
}
}
// The output contains the path and parameters like ("aeds", newAED)
let result: (path: String, parameters: [String: AnyObject]?) = {
switch self {
case .GetAEDInRange(let parameters):
return ("aeds", parameters)
}()
// Generate URL Request
let URL = NSURL(string: Router.baseURLString)!
// Append the path components from the result
print(result.path)
let URLRequest = NSURLRequest(URL: URL.URLByAppendingPathComponent(result.path))
// Create URLRequest inclunding the encoded parameters
let encoding = Alamofire.ParameterEncoding.JSON
let (encodedRequest, _) = encoding.encode(URLRequest, parameters: result.parameters)
encodedRequest.HTTPMethod = method.rawValue
return encodedRequest
}
}
The output I expect is: http://BASEURL/v1/aed?latitude=100&longitude=100
When I use Alamofire to make a GET request with parameters attached, it works fine:
Alamofire.request(.GET, "http://SERVER/v1/aeds", parameters: parameters).responseJSON { (response) -> Void in
print(response.result.value)
}
When I use my router instead, the output is not generated as expected:
Alamofire.request(Router.GetAEDInRange(parameters)).responseJSON { (response) -> Void in
print(response.result.value)
}
When I print the URL String, I get: `http://SERVER/v1/aeds/``
How do I need to change my router? I struggle with the parameter component somehow.
Change this line
let encoding = Alamofire.ParameterEncoding.JSON
to this:
let encoding = Alamofire.ParameterEncoding.URLEncodedInURL
To understand the difference between Parameter Encodings in Alamofire take a look here.
Swift3
'Alamofire', '~> 4.0'
let parameters: [String: Any] = [
"parameter1" : data1,
"parameter2" : data2
]
Alamofire.request("https://httpbin.org/get", parameters: parameters, encoding: URLEncoding(destination: .queryString))
I am trying to access my MAMP database webservice using Alamofire. Following is my code:
Following is my router to construct my URL:
enum Router: URLRequestConvertible {
static let baseURLString = "http://pushchat.local:44447/"
case PostJoinRequest(String,String,String,String,String)
var URLRequest: NSURLRequest {
let (path: String, parameters: [String: AnyObject]) = {
switch self {
case .PostJoinRequest (let addPath, let userID, let token, let nickName, let secretCode):
let params = ["cmd": "join", "user_id": "\(userID)", "token": "\(token)", "name": "\(nickName)", "code": "\(secretCode)"]
return (addPath, params)
}
}()
let URL = NSURL(string: Router.baseURLString)
let URLRequest = NSURLRequest(URL: URL!.URLByAppendingPathComponent(path))
let encoding = Alamofire.ParameterEncoding.URL
return encoding.encode(URLRequest, parameters: parameters).0
}
}
Following is my viewdidload code:
Alamofire.request(.POST,Router.PostJoinRequest("api.php","12345678901234","12345678901234","ABCDEF","TopSecret")).responseJSON()
{(request, response, JSON, error) in
println(JSON)
}
Following is the compile error:
Cannot invoke 'responseJSON' with an argument list of type '((,,,)->_)'
Following is the declaration from Almofire for your reference.
:param: method The HTTP method.
:param: URLString The URL string.
:param: parameters The parameters. `nil` by default.
:param: encoding The parameter encoding. `.URL` by default.
:returns: The created request.
*/
// public func request(method: Method, _ URLString: URLStringConvertible, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL) -> Request {
// return request(encoding.encode(URLRequest(method, URLString), parameters: parameters).0)
// }
Please let me know why am I facing this issue while chaining and what is it that I am not doing right?
Thanks for your help.
Dev
The compiler error message is really misleading – there is no problem with responseJSON but with request method itself.
In fact compiler does not like your second parameter. You are passing URLRequestConvertible but URLStringConvertible is expected (see the signature you posted).
Maybe you wanted to call another version of request method:
//:param: URLRequest The URL request
//:returns: The created request.
public func request(URLRequest: URLRequestConvertible) -> Request
In that case you have to adjust your Router class and set HTTP method into NSURLRequest created inside. For example:
let URLRequest = NSMutableURLRequest(URL: URL!.URLByAppendingPathComponent(path))
URLRequest.HTTPMethod = "POST"
Note you will also probably need to use another parameter/data encoding.