[英]swift - My Protocol and Delegate isn't working
我创建了一个名为 TermProtocol 的协议,其中包含一个名为 gotTerm 的 function。 每当用户在我的视图(CategoryView)中按下此按钮时,委托都应该获得回调并运行我设置的代码。 在我的例子中,代表将是 AppDelegate。 我在应用程序委托中名为 gotTerm 的 function 中放置了一条打印语句,以便我可以查看代码是否真的在运行,但我从未在控制台中看到我在打印语句中放入的短语。 我认为我的代表没有收到回调。 任何人都可以帮助我吗?
这是我的代码:
术语协议:
protocol TermProtocol: class{
func gotTerm()
}
CategoryView.Swift
struct CategoryView: View {
var foodCategory: String
let appDelegate = UIApplication.shared.delegate as? AppDelegate
var delegate: TermProtocol?
var body: some View {
NavigationView {
NavigationLink(destination: RestrauntView()) {
Image("Find Button")
.renderingMode(.original)
}.simultaneousGesture(TapGesture().onEnded{
print("didtapallow 4")
self.appDelegate!.terms = self.foodCategory
self.delegate?.gotTerm()
})
Spacer()
}
}
}
struct CategoryView_Previews: PreviewProvider {
static var previews: some View {
CategoryView(foodCategory: "Chinese Food")
}
}
AppDelegate.swift
import UIKit
import CoreData
import Moya
import Alamofire
import CoreLocation
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, TermProtocol {
func gotTerm() {
print("did get term")
let lat = self.locationService.setup(latOrLong: "lat")
let long = self.locationService.setup(latOrLong: "long")
self.locationService.lat = lat
self.locationService.long = long
self.loadBusinesses(lat: lat, long: long, theTerm: self.terms)
}
var theViewModels = [RestrauntListViewModel]()
let locationService = LocationService()
var terms = ""
var categoryView = CategoryView(foodCategory: "indian")
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
categoryView.delegate = self
let dataSource = DataSource()
print("this is the view models in appDelegate: \(theViewModels)")
locationService.didChangeStatus = { [weak self] success in
print("did tap allow 1")
if success {
self?.locationService.getLocation()
}
}
locationService.newLocation = { [weak self] result in
print("did tap allow 2")
switch result {
case .success(let location):
self?.loadBusinesses(lat: location.coordinate.latitude, long: location.coordinate.longitude, theTerm: "chinese")
case .failure(let error):
assertionFailure("Error getting the users location \(error)")
}
}
locationService.setup(latOrLong: "lat")
return true
}
func loadBusinesses (lat: Double, long: Double, theTerm: String) {
let service = MoyaProvider<YelpService.BusinessProvider>()
let jsonDecoder = JSONDecoder()
let restrauntView = RestrauntView()
let appDelegate = AppDelegate()
print("The latitude of u is \(lat) and the long of you is \(long)")
if CLLocationManager.locationServicesEnabled() {
switch CLLocationManager.authorizationStatus() {
case .notDetermined, .restricted, .denied:
print("No access")
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
service.request(.search(lat: lat, long: long, term: theTerm)) { (result) in
switch result{
case.success(let response):
print("yaya")
let root = try? jsonDecoder.decode(Root.self, from: response.data)
let viewModels = root?.businesses.compactMap(RestrauntListViewModel.init)
let dataSource = DataSource()
dataSource.arrayOfImages.removeAll()
for image in viewModels! {
Alamofire.request(image.imageURL).responseImage { response in
if let image = response.result.value {
print("image downloadedline 59 appdelegate")
dataSource.arrayOfImages.append(image)
print(dataSource.arrayOfImages)
} else {
print("ERROR: image does not = response.result.value")
}
}
}
self.theViewModels = (root?.businesses.compactMap(RestrauntListViewModel.init))!
print(" restrauntView.theViewModels is here \(restrauntView.theViewModels)")
print("the constant theViewModels in the appdelegate has \(appDelegate.theViewModels.count) values")
case .failure(let error):
print("Error: \(error)")
}
}
@unknown default:
break
}
} else {
print("Location services are not enabled")
}
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "Actrual_Food_Circle")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
我将首先说明您不应该在 SwiftUI 中以这种方式使用委托和闭包。 这是使用 SwiftUI - https://nalexn.github.io/clean-architecture-swiftui对干净 MVVM 架构的一个很好的介绍
我相信您会想要添加 ViewModel 来处理应用程序中的这些状态。
回到回答你的问题 - 我认为在这种情况下添加 闭包将是最快(不一定正确)的解决方案:
struct ContentView: View {
var gotTermCallback: (()->())?
var body: some View {
NavigationView {
NavigationLink(destination: Text("test")) {
...
}.simultaneousGesture(TapGesture().onEnded{
...
self.gotTermCallback?()
})
...
}
}
}
然后您可以通过简单地调用以下代码将其添加到某种处理程序或副作用处理程序中:
var contentView: ContentView = ContentView()
contentView.gotTermCallback = {
print("[DEBUG] - terms callback")
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.