将 url 从标记传递到控制器

Pass the url from the marker into the controller

我正在开发用于查看 IP 摄像机的应用程序,并希望将摄像机添加到地图,这样您就可以单击所需的标记并查看所需的摄像机。我有一个地图和 PlayerViewController 可以重现网络摄像头。

现在每个标记只传输网络摄像头的第一个流。帮我。如何使不同的网络摄像头工作?

ViewController

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    var moscow: [(name: String, URLs:String, img:String, latitude: Double, longitude: Double)] =
    [("cam1", "http://example/1.m3u8", "1.jpg", 55.753989, 37.620235),
     ("cam2", "http://example/2.m3u8", "2.jpg", 55.741308, 37.653914),
     ("cam3","http://example/3.m3u8","3.jpg", 55.742468, 37.629292)]

    override func viewDidLoad() {
        super.viewDidLoad()

        var latitudes = moscow.map({ [=11=].latitude })
        var longitudes = moscow.map({ [=11=].longitude })
        var annotations = moscow.map({ [=11=].name })

        for i in 0...2 {
            let coordinate = CLLocationCoordinate2DMake(latitudes[i], longitudes[i])
            let span = MKCoordinateSpanMake(0.003, 0.003)
            let region = MKCoordinateRegionMake(coordinate, span)
            mapView.setRegion(region, animated:true)

            let annotation = MKPointAnnotation()
            annotation.coordinate = coordinate
            annotation.title = annotations[i]
            self.mapView.addAnnotation(annotation)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
        print(#function)
    }

    // Called when the annotation was added
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation {
            return nil
        }

        let reuseId = "pin"
        var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
        if pinView == nil {
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            pinView?.animatesDrop = true
            pinView?.canShowCallout = true
            pinView?.isDraggable = true
            pinView?.pinColor = .purple

            let rightButton: AnyObject! = UIButton(type: UIButtonType.detailDisclosure)
            pinView?.rightCalloutAccessoryView = rightButton as? UIView
        } else {
            pinView?.annotation = annotation
        }

        return pinView
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        print(#function)

        if control == view.rightCalloutAccessoryView {
            performSegue(withIdentifier: "toTheMoon", sender: self)
        }
    }

    override  func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toTheMoon" {
            let controller = segue.destination as! PlayerViewController

            var urlll = moscow.map({ [=11=].URLs })

            for i in 0...2 {
                controller.webcamURL = urlll[i] // only first cam play
            }
        }
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
        if newState == MKAnnotationViewDragState.ending {
            let droppedAt = view.annotation?.coordinate
            print(droppedAt)
        } 
    }
}

玩家ViewController

import UIKit
import AVFoundation
import AVKit

class PlayerViewController: AVPlayerViewController {

    var webcamURL:  String!
    var webcamTitle: String!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = webcamTitle
        let url = URL(string: webcamURL)
        player = AVPlayer(url: url!)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        player!.play()     
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.player!.pause()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        player = nil
    }
}

首先 MKAnnotation 是一个协议,所以你可以在你的模型 class 中实现这个协议,假设 "Camera"

import UIKit
import MapKit

class Camera: NSObject, MKAnnotation {

    var name: String = ""
    var urlString :String = ""
    var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0, longitude: 0)
    var imageName : String = ""

    init(name:String,camUrl:String,imageNamed:String,latitude:CLLocationDegrees,longitude:CLLocationDegrees) {
        super.init()
        self.name = name
        self.urlString = camUrl
        self.imageName = imageNamed

        guard latitude != 0 && longitude != 0 else
        {
            return
        }

        guard latitude.isNaN || longitude.isNaN else
        {
            return
        }

        self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }

    // Title and subtitle for use by selection UI.
    public var title: String? {
        get{
            return self.name
        }
    }

}

然后你可以像这样减少你的 ViewController 代码

import UIKit
import MapKit

class ViewController: UIViewController {

    @IBOutlet weak var mapView: MKMapView!
    var moscow: [Camera] = []
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.moscow = [Camera(name: "cam1", camUrl: "http://example/1.m3u8", imageNamed: "1.jpg", latitude: 55.753989, longitude: 37.620235),
                       Camera(name: "cam2", camUrl: "http://example/2.m3u8", imageNamed: "2.jpg", latitude: 55.741308, longitude: 37.653914),
                       Camera(name: "cam3", camUrl: "http://example/3.m3u8", imageNamed: "3.jpg", latitude: 55.742468, longitude: 37.629292)]

        self.mapView.addAnnotations(self.moscow)
        self.mapView.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

extension ViewController : MKMapViewDelegate
{
    func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
        print(#function)
    }

    // Called when the annotation was added
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation {
            return nil
        }

        let reuseId = "pin"
        var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
        if pinView == nil {
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            pinView?.animatesDrop = true
            pinView?.canShowCallout = true
            pinView?.isDraggable = true
            pinView?.pinColor = .purple

            let rightButton: AnyObject! = UIButton(type: UIButtonType.detailDisclosure)
            pinView?.rightCalloutAccessoryView = rightButton as? UIView
        } else {
            pinView?.annotation = annotation
        }

        return pinView
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        print(#function)

        let camera = view.annotation as! Camera
        if control == view.rightCalloutAccessoryView {
            performSegue(withIdentifier: "toTheMoon", sender: camera)
        }
    }

    override  func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toTheMoon" {
            let controller = segue.destination as! PlayerViewController

            controller.webcamURL = (sender as! Camera).urlString
            controller.webcamTitle = (sender as! Camera).name
        }
    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
        if newState == MKAnnotationViewDragState.ending {
            let droppedAt = view.annotation?.coordinate
            print(droppedAt)
        } 
    }

}

希望对您有所帮助