我正在尝试执行 POST 请求,但请求没有通过。我已经看过 Perform POST request in Swift已经,但它不包含我正在寻找的内容。
func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
var request = NSMutableURLRequest(URL: NSURL(string: "https://us1.lacunaexpanse.com"))
println("request url https://us1.lacunaexpanse.com")
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
let apikey = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
println("apikey",apikey)
let username = "username"
let password = "password"
var login = Array(["username", "password", "apikey"])
let jsonDictionary = ["2.0", "jsonrpc", "1", "id", "login", "method", "login", "params"]
println("jsonDictionary",jsonDictionary)
var writeError: NSError?
let jsonData = NSJSONSerialization.dataWithJSONObject(jsonDictionary, options: NSJSONWritingOptions(), error: NSErrorPointer())
var resultAsString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)
resultAsString = resultAsString.stringByAppendingString("empire")
let url = NSURL.URLWithString("string")
println("url",url)
var request2 = NSMutableURLRequest()
println("Post url =%@",url)
request2 = NSMutableURLRequest(URL:url)
request2.HTTPMethod = "POST"
var connection = NSURLConnection(request: request, delegate: self, startImmediately: false)
return true
最佳答案
这里有一大堆战术问题:
您正在创建 URLSession,然后发出 NSURLConnection 请求。只需使用 URLSession。
您的“请求字典”不是字典,而是数组。例如发出JSON-RPC请求,字典的正确格式是:
let requestDictionary: [String: Any] = [
"jsonrpc" : "2.0",
"id" : 1,
"method" : "login",
"params" : ["myuserid", "mypassword", "mykey"]
]
小问题,但是您使用了很多变量(通过 var),而常量(通过 let)就可以了。本着 Swift 的安全精神,尽可能使用 let。
根据 Lacuna Expanse API ,您的 URL 应该包含模块名称。
因此,例如,如果在“Empire”模块中执行POST 请求,则URL 是:
let url = URL(string: "https://us1.lacunaexpanse.com/empire")!
您可能会执行大量请求,因此我建议将大部分请求放在一个可以反复调用的函数中,而无需到处重复代码。也许像下面这样的函数采用以下参数:
模块(例如“帝国”与“联盟”);
方法(例如“登录”与“获取验证码”);
适合该请求的参数(例如,对于“登录”,这将是“名称”、“密码”和“api_key”);和
将在异步请求完成时调用的闭包。
此函数然后准备 JSON-RPC 请求并在请求完成时调用闭包:
@discardableResult
func submitLacunaRequest(module: String, method: String, parameters: Any, completion: @escaping (Result<[String: Any], Error>) -> Void) -> URLSessionTask? {
let session = URLSession.shared
let url = URL(string: "https://us1.lacunaexpanse.com")!
.appendingPathComponent(module)
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json-rpc", forHTTPHeaderField: "Content-Type")
let requestDictionary: [String: Any] = [
"jsonrpc": "2.0",
"id" : 1,
"method" : method,
"params" : parameters
]
request.httpBody = try! JSONSerialization.data(withJSONObject: requestDictionary)
let task = session.dataTask(with: request) { data, response, error in
// handle fundamental network errors (e.g. no connectivity)
guard error == nil, let data = data else {
completion(.failure(error ?? URLError(.badServerResponse)))
return
}
// check that http status code was 200
guard
let httpResponse = response as? HTTPURLResponse,
200 ..< 300 ~= httpResponse.statusCode
else {
completion(.failure(URLError(.badServerResponse)))
return
}
// parse the JSON response
do {
guard let responseObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
throw URLError(.badServerResponse)
}
completion(.success(responseObject))
} catch let parseError {
completion(.failure(parseError))
}
}
task.resume()
return task
}
这会在 JSON-RPC 请求中对方法和参数进行所有必要的包装。然后,您需要做的就是调用该方法:
submitLacunaRequest(module: "empire", method: "login", parameters: ["myuserid", "mypassword", "mykey"]) { result in
switch result {
case .failure(let error):
print("error = \(error)")
case .success(let value):
if let errorDictionary = value["error"] as? [String: Any] {
print("error logging in (bad userid/password?): \(errorDictionary)")
} else if let resultDictionary = value["result"] as? [String: Any] {
print("successfully logged in, refer to resultDictionary for details: \(resultDictionary)")
} else {
print("we should never get here")
print("responseObject = \(value)")
}
}
}
对于需要字典的请求,例如“创建”,只需提供字典即可:
submitLacunaRequest(module:"empire", method: "create", parameters: [
"name" : "user",
"password" : "password",
"password1" : "password",
"captcha_guid" : "305...dd-....-....-....-e3706...73c0",
"captcha_solution" : "42",
"email" : "test@gmail.com"
]) { result in
switch result {
case .failure(let error):
print("error = \(error)")
case .success(let value):
print("responseObject = \(responseObject)")
}
}
很明显,在上面这些中,我只是做了最少的错误处理,所以你可以加强这个,但你的问题是关于发出 POST 请求,希望上面说明了这是如何完成的。
有关 Swift 2 版本,请参阅 previous revision这个答案。
关于ios - 在 iOS Swift 中执行 POST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25341858/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送