【发布时间】:2018-01-08 16:24:01
【问题描述】:
我有一个调用并等待服务器响应的函数。我想在请求之前显示活动指示器,并在对同一功能的回答之后隐藏它。为什么?避免代码重复。我将在其他操作中调用服务器。
它现在的工作方式是:手动调用登录按钮上的开始和停止动画。
为了测试指标,我在服务器上添加了 sleep。
问题:如何显示/隐藏每次调用服务器的指示器?
登录视图上的按钮:
@IBAction func btnLog2(_ sender: Any) {
DispatchQueue.main.async(execute: {
customActivityIndicatory(self.view, startAnimate: true)
})
let user = User(email: login_email.text!, password : login_password.text!)
var jsonData = Data()
let jsonEncoder = JSONEncoder()
do {
jsonData = try jsonEncoder.encode(user)
}
catch {
}
makeRequestPost(endpoint: "http://blog.local:4711/api/login",
requestType: "POST",
requestBody: jsonData,
completionHandler: { (response : ApiContainer<Login>?, error : Error?) in
if let error = error {
print("error calling POST on /todos")
print(error)
return
}
DispatchQueue.main.async(execute: {
customActivityIndicatory(self.view, startAnimate: false)
})
let a = (response?.result[0])!
let b = (response?.meta)!
if(b.sucess == "yes") {
DAKeychain.shared["email"] = (user.email) // Store
DAKeychain.shared["token"] = (a.token) // Store
DispatchQueue.main.async(execute: {
let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "tabBarClients") as UIViewController
self.present(viewController, animated: false, completion: nil)
})
}
else
{
DispatchQueue.main.async(execute: {
let myAlert = UIAlertController(title: "Error", message: "Invalid E-mail or Password", preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
myAlert.addAction(okAction)
self.present(myAlert, animated: true, completion: nil)
})
}
} )
}
请求函数
func makeRequestPost<T>(endpoint: String,
requestType: String = "GET",
requestBody: Data,
completionHandler: @escaping (ApiContainer<T>?, Error?) -> ()) {
guard let url = URL(string: endpoint) else {
print("Error: cannot create URL")
let error = BackendError.urlError(reason: "Could not create URL")
completionHandler(nil, error)
return
}
var urlRequest = URLRequest(url: url)
let session = URLSession.shared
urlRequest.httpMethod = "POST"
urlRequest.httpBody = requestBody
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTask(with: urlRequest, completionHandler: {
(data, response, error) in
guard let responseData = data else {
print("Error: did not receive data")
completionHandler(nil, error)
return
}
guard error == nil else {
completionHandler(nil, error!)
return
}
do {
let response = try JSONDecoder().decode(ApiContainer<T>.self, from: responseData)
completionHandler(response, nil)
}
catch {
print("error trying to convert data to JSON")
print(error)
completionHandler(nil, error)
}
})
task.resume()
}
帮助文件的功能:
func makeRequestPost<T>(endpoint: String,
requestType: String = "GET",
requestBody: Data,
completionHandler: @escaping (ApiContainer<T>?, Error?) -> ()) {
guard let url = URL(string: endpoint) else {
print("Error: cannot create URL")
let error = BackendError.urlError(reason: "Could not create URL")
completionHandler(nil, error)
return
}
var urlRequest = URLRequest(url: url)
let session = URLSession.shared
urlRequest.httpMethod = "POST"
urlRequest.httpBody = requestBody
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTask(with: urlRequest, completionHandler: {
(data, response, error) in
guard let responseData = data else {
print("Error: did not receive data")
completionHandler(nil, error)
return
}
guard error == nil else {
completionHandler(nil, error!)
return
}
do {
let response = try JSONDecoder().decode(ApiContainer<T>.self, from: responseData)
completionHandler(response, nil)
}
catch {
print("error trying to convert data to JSON")
print(error)
completionHandler(nil, error)
}
})
task.resume()
}
编辑:
我创建了一个 CustomActivityIndicator 类,但没有显示加载器。开始和停止打印在控制台上。
import Foundation
import UIKit
class CustomActivityIndicator {
var viewContainer = UIView()
var startAnimate:Bool? = true
var mainContainer = UIView()
var activityIndicatorView = UIActivityIndicatorView()
let viewBackgroundLoading = UIView()
init(viewContainer: UIView, startAnimate: Bool?) {
self.viewContainer = viewContainer
self.startAnimate = startAnimate
setup()
}
func setup() {
let mainContainer: UIView = UIView(frame: viewContainer.frame)
mainContainer.center = viewContainer.center
mainContainer.backgroundColor = UIColor.lightGray
mainContainer.alpha = 0.5
mainContainer.tag = 789456123
mainContainer.isUserInteractionEnabled = true
let viewBackgroundLoading: UIView = UIView(frame: CGRect(x:0,y: 0,width: 80,height: 80))
viewBackgroundLoading.center = viewContainer.center
viewBackgroundLoading.backgroundColor = UIColor.black
viewBackgroundLoading.alpha = 0.5
viewBackgroundLoading.clipsToBounds = true
viewBackgroundLoading.layer.cornerRadius = 15
let activityIndicatorView: UIActivityIndicatorView = UIActivityIndicatorView()
activityIndicatorView.frame = CGRect(x:0.0,y: 0.0,width: 40.0, height: 40.0)
activityIndicatorView.activityIndicatorViewStyle =
UIActivityIndicatorViewStyle.whiteLarge
activityIndicatorView.center = CGPoint(x: viewBackgroundLoading.frame.size.width / 2, y: viewBackgroundLoading.frame.size.height / 2)
}
func start(){
DispatchQueue.main.async(execute: {
print("start")
self.viewBackgroundLoading.addSubview(self.activityIndicatorView)
self.mainContainer.addSubview(self.viewBackgroundLoading)
self.viewContainer.addSubview(self.mainContainer)
self.activityIndicatorView.startAnimating()
})
}
func stop() {
DispatchQueue.main.async(execute: {
print("stop")
for subview in self.viewContainer.subviews {
if subview.tag == 789456123{
subview.removeFromSuperview()
}
}
})
}
}
内部函数 makeRequestPost
func makeRequestPost<T>(endpoint: String,
requestType: String = "GET",
requestBody: Data,
activityIndicator: CustomActivityIndicator? = nil,
completionHandler: @escaping (ApiContainer<T>?, Error?) -> ()) {
activityIndicator?.start() .......
在操作按钮上:
let loading = CustomActivityIndicator(viewContainer: self.view, startAnimate: true)
makeRequestPost(endpoint: "http://blog.local:4711/api/login",
requestType: "POST",
requestBody: jsonData,
activityIndicator: loading,
completionHandler: { (response : ApiContainer<Login>?, error : Error?) in
【问题讨论】: