gpt4 book ai didi

ios - 通信协议(protocol)/委托(delegate)上的 Swift 错误

转载 作者:行者123 更新时间:2023-11-30 12:20:11 25 4
gpt4 key购买 nike

我正在使用 Swift 3 开发一个应用程序。现在我必须在两个 View Controller (带有协议(protocol)和委托(delegate))之间传递一个值。我收到错误:

fatal error: unexpectedly found nil while unwrapping an optional value.

因为delegate变量的值为nil。该委托(delegate)定义为 var delegate: LeftSideDelegate!,我将其称为 delegate.sendShapeDelivery()

调用它的函数didTappedSwicht是另一个协议(protocol)的方法(它不必影响它?)。

有谁知道为什么会出现这个错误?

import UIKit

protocol LeftSideDelegate {
func sendShapeDelivery(deliveryPos: Int)
}

class LeftSideViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, customCellDelegate {

var selectedIndex = -1
var feedModelDeliveries: [deliveriesLeftTableModel] = [deliveriesLeftTableModel]()
var delegate: LeftSideDelegate!

@IBOutlet weak var tableSideLeft: UITableView!
@IBAction func opacityDelivery(_ sender: UISlider) {
print(sender.value)
}

//var delegate = OptionDelegate()?

override func viewDidLoad() {
super.viewDidLoad()
//tableSideLeft.isEditing = true

fillDataDeliveries()
}

func fillDataDeliveries() {
for i in 0...snapShotsLegend.legendEntries[0].deliverables.count - 1 {
let newModel = deliveriesLeftTableModel()

newModel.firstViewLabel = snapShotsLegend.legendEntries[0].deliverables[i].type
newModel.secondViewLabel = "Option " + snapShotsLegend.legendEntries[0].deliverables[i].type
newModel.idDeliveryResponse = snapShotsLegend.legendEntries[0].deliverables[i].options[0].id
newModel.initialMaxDeliveryResponse = String(snapShotsLegend.legendEntries[0].deliverables[i].options[0].initial_max_value)
newModel.initialMinDeliveryResponse = String(snapShotsLegend.legendEntries[0].deliverables[i].options[0].initial_min_value)
newModel.maxRangeDeliveryResponse = String(snapShotsLegend.legendEntries[0].deliverables[i].options[0].max_range)
newModel.minRangeDeliveryResponse = String(snapShotsLegend.legendEntries[0].deliverables[i].options[0].min_range)
feedModelDeliveries.append(newModel)
}

tableSideLeft.delegate = self
tableSideLeft.dataSource = self
}

func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return snapShotsLegend.legendEntries[0].deliverables.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! customCell
cell.setupWithModel(model: feedModelDeliveries[indexPath.row])
cell.delegate = self as customCellDelegate

return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if (selectedIndex == indexPath.row) {
return 300
} else {
return 60
}
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if (selectedIndex == indexPath.row) {
selectedIndex = -1
} else {
selectedIndex = indexPath.row
}

self.tableSideLeft.beginUpdates()
self.tableSideLeft.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
self.tableSideLeft.endUpdates()
}

//MARK: FUNCTIONS ALLOWS REORDERING OF CELLS
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}

func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let item = snapShotsLegend.legendEntries[0].deliverables[sourceIndexPath.row]
snapShotsLegend.legendEntries[0].deliverables.remove(at: sourceIndexPath.row)
snapShotsLegend.legendEntries[0].deliverables.insert(item, at: destinationIndexPath.row)
}

func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.none
}

func didTappedSwicht(cell: customCell) {
let indexPath = tableSideLeft.indexPath(for: cell)

feedModelDeliveries[(indexPath?.row)!].swichtActiveLayer = cell.swichtActiveLayer.isOn

if cell.swichtActiveLayer.isOn {
print("SHOW DELIVERY TO MAP, LAYER -> \( snapShotsLegend.legendEntries[0].deliverables[(indexPath?.row)!].url_layer)")

// MARK: SWICHT ON (NOT EXIST DELIVERABLE / EXIST DELIVERABLE)
if feedModelDeliveries[(indexPath?.row)!].tileLayer == nil {
delegate.sendShapeDelivery(deliveryPos: (indexPath?.row)!)
// MARK: SWICHT OFF
} else {
print("Exist deliverable -> not call WMS")
}
} else {
print("HIDE DELIVERY TO MAP, LAYER -> \( snapShotsLegend.legendEntries[0].deliverables[(indexPath?.row)!].url_layer)")
}
}

func didMoveSlider(cell: customCell) {
let indexPath = tableSideLeft.indexPath(for: cell)
feedModelDeliveries[(indexPath?.row)!].sliderOpacity = cell.sliderOpacity.value
}
}

我调用协议(protocol)(在ende)函数的代码是:

import UIKit
import GoogleMaps
import MapKit
import ObjectMapper



//MARK: GLOBAL VARIABLES
let showLegend = UserDefaults.standard
let showLegendInformation = "showLegend"
var fields:WFSModel = WFSModel()
var allFields:[Field] = [Field]()
var total_parcels:[Parcel] = [Parcel]()
var poligons: [GMSPolygon] = []
var holes: [GMSMutablePath] = []
var snapShotsLegend : SnapshotsLegendModel = SnapshotsLegendModel()
var allDeliveries: [GMSURLTileLayer] = []

class MainMapVC: UIViewController, UISearchBarDelegate, CLLocationManagerDelegate, GMSMapViewDelegate {

//OUTLETS:
@IBOutlet weak var dragLegend: NSLayoutConstraint!
@IBOutlet weak var iconDragLegend: UIImageView!
@IBOutlet weak var mapView: GMSMapView!
@IBOutlet weak var timer: UIActivityIndicatorView!
@IBOutlet weak var dragLengendView: UIView!
@IBOutlet weak var iconBarLegend: UIBarButtonItem!


//MARK: VARIABLES
let layer: WMSTileOverlay
var window: UIWindow?
var centerContainer: MMDrawerController?
var url = ""
let locationManager = CLLocationManager()
var coordenatesCellSelected: [Double] = [Double]()
var hole = GMSMutablePath()
var wfs:WFSModel = WFSModel()
var rect = GMSMutablePath()
let start = NSDate();
var polygonSelect = GMSPath()
var posSelecteTable:Int = 0
var menu_vc: LeftSideViewController!



//MARK:VIEWS
override func viewWillAppear(_ animated: Bool) {
super.viewDidLoad()

if coordenatesCellSelected.count != 0 {
let bounds = GMSCoordinateBounds(path: poligons[posSelecteTable].path!)
self.mapView!.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 15.0))
poligons[posSelecteTable].fillColor = UIColor(red: 8/256, green: 246/255, blue: 191/255, alpha: 0.9)
poligons[posSelecteTable].strokeColor = .blue
poligons[posSelecteTable].strokeWidth = 2
poligons[posSelecteTable].map = mapView
}

if showLegend.bool(forKey: showLegendInformation) == true {

//self.dragLengendView.isHidden = false
self.iconBarLegend.isEnabled = true


}
}




override func viewDidLoad() {
super.viewDidLoad()

menu_vc = self.storyboard?.instantiateViewController(withIdentifier: "LeftSideViewController") as! LeftSideViewController

self.timer.startAnimating()

locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
mapView.isMyLocationEnabled = true
mapView.settings.myLocationButton = true

url = ""

let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToGesture))
swipeRight.direction = UISwipeGestureRecognizerDirection.right

let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToGesture))
swipeRight.direction = UISwipeGestureRecognizerDirection.left

self.view.addGestureRecognizer(swipeRight)
self.view.addGestureRecognizer(swipeLeft)

if showLegend.bool(forKey: showLegendInformation) == false {


self.iconBarLegend.tintColor = UIColor.clear
self.iconBarLegend.isEnabled = false
}


if !allFields.isEmpty{
drawFields()
}

if allFields.isEmpty{
self.getCardfromGeoserver()
}
self.mapView.mapType = .satellite

}

@IBAction func menu_action(_ sender: UIBarButtonItem) {

if AppDelegate.menu_bool{
show_menu_left()
}else{
close_menu_left()
}

}

func show_menu_left(){

UIView.animate(withDuration: 0.6) { ()->Void in

self.menu_vc.view.frame = CGRect(x: 0, y: 60, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
self.menu_vc.view.backgroundColor = UIColor.black.withAlphaComponent(0.6)
self.addChildViewController(self.menu_vc)
self.view.addSubview(self.menu_vc.view)
AppDelegate.menu_bool = false
}

}


func close_menu_left(){

UIView.animate(withDuration: 0.6, animations: { ()->Void in
self.menu_vc.view.frame = CGRect(x: -UIScreen.main.bounds.size.width, y: 60, width: -UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
}) { (finished) in

self.menu_vc.view.removeFromSuperview()
}

AppDelegate.menu_bool = true

}


func respondToGesture(gesture: UISwipeGestureRecognizer){
switch gesture.direction{
case UISwipeGestureRecognizerDirection.right:
show_menu_left()

case UISwipeGestureRecognizerDirection.left:
close_on_swipe()

default:
break

}
}

func close_on_swipe(){

if AppDelegate.menu_bool{
show_menu_left()
}else{
close_menu_left()
}

}

//MARK: FUNCITIONS
required init?(coder aDecoder: NSCoder) {
self.layer = WMSTileOverlay(urlArg: url)
super.init(coder: aDecoder)
}


func getCardfromGeoserver() {
mapView.clear()

//mapView.camera = GMSCameraPosition(target: CLLocationCoordinate2D(latitude: 40.4256572451179, longitude: -3.18201821297407), zoom: 5.5, bearing: 0, viewingAngle: 0)


//MAP POSITION WITH DIFERENTS LAYERS
mapView.camera = GMSCameraPosition(target: CLLocationCoordinate2D(latitude: 39.59955969890008, longitude: -0.6421281303940684), zoom: 18.0, bearing: 0, viewingAngle: 0)






let WFS_JSON = "http://192.168.5.57:8080/geoserver/LordWor/wfs?service=WFS&version=1.0.0&request=GetFeature&typeName=LordWor:hemav-fincas&maxFeatures=1721&outputFormat=json"

if allFields.isEmpty {
let mapsFacade = MapsFacade()
mapsFacade.coordinatesWFS(url: WFS_JSON,
callbackFuncionOK: coordinatesWFSOK,
callbackFunctionERROR: coordinatesWFSOKERROR)
}



}



func coordinatesWFSOK( WFS_Response: WFSModel) {
let fields = WFS_Response.copyFieldswfs()
wfs = WFS_Response

for feature in 1...(wfs.features.count) {
//MARK: INSERT DATA FIELDS
DataBaseManagement.shared.addFields(inputPropertyIDFarming : wfs.features[feature - 1].properties.propertyIDFarming,
inputPropertyProducer : wfs.features[feature - 1].properties.propertyProducer,
inputPropertyVariety : wfs.features[feature - 1].properties.propertyVariety,
inputPropertyLand : wfs.features[feature - 1].properties.propertyLand)


for parcel in 1...(wfs.features[feature - 1].geometry.coordinates.count) {

if wfs.features[feature - 1].geometry.coordinates[parcel - 1].count == 1{//MARK: Without Hole
for poligon in 1...(wfs.features[feature - 1 ].geometry.coordinates[parcel - 1].count) {

//MARK: INSERT DATA FIELDS
DataBaseManagement.shared.addParcels(inputId_field: feature, inputCoordinatesJSON: String(describing: wfs.features[feature - 1].geometry.coordinates[0][0]))

}

}else{
for id in 1...(wfs.features[feature - 1].geometry.coordinates[parcel - 1].count) {//MARK: With Hole

if id == 1{
//MARK: INSERT COOERDENATES PARCEL
DataBaseManagement.shared.addParcels(inputId_field: feature, inputCoordinatesJSON: String(describing: wfs.features[feature - 1].geometry.coordinates[0][0]))

}else{
//MARK: this row contains all points for create a hole
//DataBaseManagement.shared.addHoles(inputId_hole: parcel, inputCoordinatesJSON: String(describing: wfs.features[feature - 1].geometry.coordinates[0][id - 1]))
//print("-------FIN PARCELA HOLE \(id - 1)---------")
}

/*for poligon in 0...(wfs.features[feature].geometry.coordinates[coordinate][id].count - 1 ) {
if id == 0{//First polygon is all field without holes


let longitude:Double = wfs.features[feature].geometry.coordinates[coordinate][id][poligon][0]
let latitude:Double = wfs.features[feature].geometry.coordinates[coordinate][id][poligon][1]
rect.add(CLLocationCoordinate2D(latitude: latitude, longitude: longitude))
}else{
//let insertHole = DataBaseManagement.shared.addParcels(inputId_field: poligon, inputCoordinatesJSON: String(describing: wfs.features[feature].geometry.coordinates))
let longitude:Double = wfs.features[feature].geometry.coordinates[coordinate][id][poligon][0]
let latitude:Double = wfs.features[feature].geometry.coordinates[coordinate][id][poligon][1]
hole.add(CLLocationCoordinate2D(latitude: latitude, longitude: longitude))
holes.append(hole)
}

}*/
}

}
}

}

//MARK: Get all group of Parcels
if allFields.count == 0 {
allFields = DataBaseManagement.shared.showAllFields()
total_parcels = DataBaseManagement.shared.showAllParcels()
}

drawFields()
}

func deleteAllParcels(){

for i in 0...total_parcels.count - 1 {
DataBaseManagement.shared.deleteAllParcels(inputId: i)
}
}

func deleteAllFields(){
for i in 0...allFields.count - 1 {
DataBaseManagement.shared.deleteAllFields(inputId: i)
}
}

func drawFields(){
//MARK: Field All Array wiht all (properrties for field and yours parcels)
for i in 0...allFields.count - 1{

let arr = try! JSONSerialization.jsonObject(with: total_parcels[i]._json_Parcel.data(using: .utf8)!, options: []) as! [[Double]]
allFields[i]._parcel.append(total_parcels[i]._json_Parcel);
//MARK: SAVE LATITUDE AND LONGITUDE IN ARRAY
for j in 0...arr.count - 1{
let longitude = arr[j][0]//latitud
let latitude = arr[j][1]//longitud

rect.add(CLLocationCoordinate2D(latitude: latitude, longitude: longitude))
}



//MARK: DRAW ON THE MAP
let polygon = GMSPolygon()
polygon.path = rect
poligons.append(polygon)
rect = GMSMutablePath()
polygon.fillColor = UIColor(red: 8/256, green: 246/255, blue: 191/255, alpha: 0.3)
polygon.strokeColor = .blue
polygon.strokeWidth = 2
polygon.map = mapView


}

let end = NSDate()
self.timer.stopAnimating()
print("TIME CHARGE 'MAIN MAP'")
print(start)
print(end)
}

let urlSnapshot = "..."
func getDeliverablesForField(){
let deliverablesFacade = DeliverablesFacade()
deliverablesFacade.snapshots(url: urlSnapshot,
callbackFuncionOK: snapshotsOK,
callbackFunctionERROR: snapshotsERROR)
}



func snapshotsOK( snapshotsResponse: SnapshotsLegendModel) {

snapShotsLegend = snapshotsResponse.copySnapshots()
print("end recover fields")

}



func snapshotsERROR(_ httpCode: Int,nsError: NSError) {
if httpCode == -1 {
print(nsError)
print(httpCode)
}else{
print(nsError)
print(httpCode)
}
}

var onlyOnetime = 0

func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {

for polygon in poligons{

if (GMSGeometryContainsLocation(CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude), polygon.path!, true)) {
onlyOnetime = onlyOnetime + 1

if onlyOnetime == 1{
getDeliverablesForField()
showLegend.setValue(true, forKey: showLegendInformation)
let bounds = GMSCoordinateBounds(path: polygon.path!)
self.mapView!.animate(with: GMSCameraUpdate.fit(bounds, withPadding: 15.0))
self.iconBarLegend.isEnabled = true
self.iconBarLegend.tintColor = UIColor.black
}

polygon.fillColor = UIColor(red: 8/256, green: 246/255, blue: 191/255, alpha: 0.9)
polygon.strokeColor = .blue
polygon.strokeWidth = 2
polygon.map = mapView

//self.viewDidLoad()
}

else{
polygon.fillColor = UIColor(red: 8/256, green: 246/255, blue: 191/255, alpha: 0.3)
polygon.strokeColor = .blue
polygon.strokeWidth = 2
polygon.map = mapView
}
}
}



func coordinatesWFSOKERROR(_ httpCode: Int,nsError: NSError) {
if httpCode == -1 {
print(nsError)
print(httpCode)
}else{
print(nsError)
print(httpCode)
}
}

@IBAction func goToAdvancedSearch(_ sender: Any) {
let advancedSearch: AdvancedSearchVC = UIStoryboard(name: "AdvancedSearch", bundle: nil).instantiateViewController(withIdentifier: "AdvancedSearchVC") as! AdvancedSearchVC
self.navigationController?.pushViewController(advancedSearch, animated: false)
}

}

扩展MainMapVC:LeftSideDelegate {

func sendShapeDelivery(deliveryPos : Int){

print("Not exist deliverable -> call WMS")
let nameDelivery = snapShotsLegend.legendEntries[0].deliverables[deliveryPos].url_layer
let urls: GMSTileURLConstructor = { (x: UInt, y: UInt, zoom: UInt) -> URL in

let bbox = self.layer.bboxFromXYZ(x, y: y, z: zoom)
let urlKN = "http://192.168.5.57:8080/geoserver/LordWor/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&tiled=true&STYLES=line&layers=LordWor:\(nameDelivery)&styles=&WIDTH=256&HEIGHT=256&SRS=EPSG:3857&BBOX=\(bbox.left),\(bbox.bottom),\(bbox.right),\(bbox.top)"
print("PETICION WMS DEL LALER: \(nameDelivery)")

return URL(string: urlKN)!
}



let tileLayer: GMSURLTileLayer = GMSURLTileLayer(urlConstructor: urls)
allDeliveries.append(tileLayer)

tileLayer.opacity = 0.5
tileLayer.map = mapView


}

}

最佳答案

MainMapVC 类内部,该行之后

menu_vc = self.storyboard?.instantiateViewController(withIdentifier: "LeftSideViewController") as! LeftSideViewController

你必须设置它的委托(delegate),如下所示:

menu_vc.delegate = self

关于ios - 通信协议(protocol)/委托(delegate)上的 Swift 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44886419/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com