Swift Error on communication Protocol/Delegate

Jordi Gallen Renau

I'm developing an application with Swift 3. And come at the point where I have to pass a value between two view controllers (with a protocol and a delegate). I get the error:

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

Because the value of the delegate variable is nil. The delegate is defined as var delegate: LeftSideDelegate!, and I call it delegate.sendShapeDelivery().

The function of where it is called didTappedSwicht is a method of another protocol (it does not have to influence it?).

Does anyone know why this error appears ?.

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
    }
}

The code where I call the protocol (at the ende) function is:

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)
}

}

extension 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


}

}
Cristian

Inside class MainMapVC, after the line

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

you have to set its delegate, like so:

menu_vc.delegate = self

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Async communication of swift and Javascriptcore

Scheduling socket communication for Swift

API Communication Bug -- Swift

Swift Core Bluetooth communication with OBD2

iOS swift socket communication: release outstream

iOS 8 swift Soap web service communication

Swift project with Javascript two way communication

Basic Java Echo Socket Communication Error

RubyMine has a communication error trying to create the SDK

GEtting Error in Pyspark communication through RPC in RabbitMq

Error avoidance when socket communication on unity

how to know communication error in google chrome extension

What is possible error on communication with TCP, UDP, serial?

Directive to directive communication throwing error in Angular

Zebra iMZ320 communication error bluetooth

Backbone, Node, and Mongo error validation and communication

Check if Error Frame is present on Communication matrix

Docusign: HTTPS required for Connect listener communication error

How to convert message received by Swift socket communication to String type

Can closure in swift be used for communication between 2 classes?

Swift BLE communication between iPhone and ESP32

Azure Communication Services - An error occurred while trying to fulfill the search request

Generic Connector Communication Error in Tomcat 8.5, BonCode AJP Connector

Docker image dies after "Got an error reading communication packets"

AngularJS directive to directive communication throwing an error about controller not found

SSIS tasks are getting fail with Communication link failure error

How to install canon LBP2900 without communication error?

Ionic run error exit code 1 device communication timed out

Healthcheck causing 'Got an error reading communication packets' messages

TOP Ranking

  1. 1

    Failed to listen on localhost:8000 (reason: Cannot assign requested address)

  2. 2

    Loopback Error: connect ECONNREFUSED 127.0.0.1:3306 (MAMP)

  3. 3

    How to import an asset in swift using Bundle.main.path() in a react-native native module

  4. 4

    pump.io port in URL

  5. 5

    Compiler error CS0246 (type or namespace not found) on using Ninject in ASP.NET vNext

  6. 6

    BigQuery - concatenate ignoring NULL

  7. 7

    ngClass error (Can't bind ngClass since it isn't a known property of div) in Angular 11.0.3

  8. 8

    ggplotly no applicable method for 'plotly_build' applied to an object of class "NULL" if statements

  9. 9

    Spring Boot JPA PostgreSQL Web App - Internal Authentication Error

  10. 10

    How to remove the extra space from right in a webview?

  11. 11

    java.lang.NullPointerException: Cannot read the array length because "<local3>" is null

  12. 12

    Jquery different data trapped from direct mousedown event and simulation via $(this).trigger('mousedown');

  13. 13

    flutter: dropdown item programmatically unselect problem

  14. 14

    How to use merge windows unallocated space into Ubuntu using GParted?

  15. 15

    Change dd-mm-yyyy date format of dataframe date column to yyyy-mm-dd

  16. 16

    Nuget add packages gives access denied errors

  17. 17

    Svchost high CPU from Microsoft.BingWeather app errors

  18. 18

    Can't pre-populate phone number and message body in SMS link on iPhones when SMS app is not running in the background

  19. 19

    12.04.3--- Dconf Editor won't show com>canonical>unity option

  20. 20

    Any way to remove trailing whitespace *FOR EDITED* lines in Eclipse [for Java]?

  21. 21

    maven-jaxb2-plugin cannot generate classes due to two declarations cause a collision in ObjectFactory class

HotTag

Archive