I have a question about periodic updating my location,with NSTimeri call periodically
:
func timerUpdate() {
func locationManager1 (manager: CLLocationManager , didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = (manager.location?.coordinate)!
_ = locManager.location!
print(locValue)
}
//self.locManager.startUpdatingLocation()
self.loctimestamp.text = "\(locManager.location!.timestamp)"
// Check if the user allowed authorization
//let loc = CLLocation()
let kur = 999
let lat = locManager.location!.coordinate.latitude
let lon = locManager.location!.coordinate.longitude
let acc = locManager.desiredAccuracy
let age = 3
let urlComponents = NSURLComponents(string: "http://example.com/track/gps.php?kur=\(kur)&lon=\(lon)&lat=\(lat)&acc=\(acc)&age=\(age)")
let urler = urlComponents!.URL
let url = urler
let request = NSURLRequest(URL: url!)
//let html = NSData(contentsOfURL: url!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
let html = NSString(data: (data)!, encoding: NSUTF8StringEncoding)
print(html)
print("Response: \(response)")
self.debug.text = ("Response: \(response)")
self.debug1.text = String(html)
}
)
task.resume()
Status.text = "an"
//locManager.stopUpdatingLocation()
}
this work fine after here come the viewdidload with
self.locManager.startUpdatingLocation()
if #available(iOS 8.0, *) {
if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse ||
CLLocationManager.authorizationStatus() == CLAuthorizationStatus.Authorized)
{
//locManager.distanceFilter.hashValue:100
locManager.pausesLocationUpdatesAutomatically = false
self.locManager.delegate = self
self.locManager.desiredAccuracy = kCLLocationAccuracyBest
self.locManager.requestAlwaysAuthorization()
// self.mapView.showUserLocation = true
if #available(iOS 9.0, *) {
locManager.allowsBackgroundLocationUpdates = true
} else {
// Fallback on earlier versions
}
and so on ,
but i just become the location from when i start the app
startUpdateLocation run but why a receive just an coordinate.timestamp one for locManager.location!.coordinate.latitude
i taught the location will be updated if location is changed
I Found the simple Solution just initiate a new CLLocationManager()
func timerUpdate() {
->>> let loco = CLLocationManager() !!!
// Check if the user allowed authorization
loctimestamp.text = "\(loco.location!.timestamp)"
//let loc = CLLocation()
let kur = 999
let lat = loco.location!.coordinate.latitude
let lon = loco.location!.coordinate.longitude
let acc = loco.desiredAccuracy
let age = 3
let urlComponents = NSURLComponents(string: "http://example.com/track/gps.php?kur=\(kur)&lon=\(lon)&lat=\(lat)&acc=\(acc)&age=\(age)")
let urler = urlComponents!.URL
let url = urler
let request = NSURLRequest(URL: url!)
//let html = NSData(contentsOfURL: url!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
let html = NSString(data: (data)!, encoding: NSUTF8StringEncoding)
print(html)
print("Response: \(response)")
self.debug.text = ("Response: \(response)")
self.debug1.text = String(html)
}
)
task.resume()
Status.text = "an"
//locManager.stopUpdatingLocation()
}
`
Related
I have tried to make a separate class for the location functionality (separate swift file in the Watchkit Exension folder) and I want to use the location instance of that class in the InterfaceController class to track the location of the user. But, xcode gets stuck and I also cannot deploy and test the application. I do not know what the reason is.
Here is the location code and the InterfaceController class:
The whole project is here: https://filebin.net/s40xlqzeukfwc39w
I hope you can help me out since I am still a beginner in terms of Swift and WatchKit. Thank you very much.
import WatchKit
import Foundation
import CoreLocation
class LocationOutside{
var locationManager: CLLocationManager = CLLocationManager()
init(){
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.delegate = (self as! CLLocationManagerDelegate)
locationManager.requestLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let currentLoc = locations[0]
let lat = currentLoc.coordinate.latitude
let long = currentLoc.coordinate.longitude
print(lat)
print(long)
}
func locationManager(_manager: CLLocationManager,didFailWithError error: Error){
if let locationErr = error as? CLError{
switch locationErr{
case CLError.locationUnknown:
print("unknown location")
case CLError.denied:
print("denied")
default:
print("another type of location error")
}
}else{
print("other error: ", error.localizedDescription)
}
}
}
import WatchKit
import Foundation
import CoreLocation
import HealthKit
import AVFoundation
import CoreMotion
let hrType:HKQuantityType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!
// Date will be constructed in database --> server side
class InterfaceController: WKInterfaceController,AVAudioRecorderDelegate{
var saveUrl: URL?
var outDoorLocation = LocationOutside.init()
// to conduct permission to retrieve location data
var locationManager: CLLocationManager = CLLocationManager()
// Outlets for testing
#IBOutlet weak var button: WKInterfaceButton!
#IBOutlet weak var furtherSigLabels: WKInterfaceLabel!
var recordingSession : AVAudioSession!
var audioRecorder : AVAudioRecorder!
var settings = [String : Any]()
// distinguish start recording heartbeat
var isRecording = false
//For workout session
let healthStore = HKHealthStore()
var session: HKWorkoutSession?
var currentQuery: HKQuery?
var filename: String?
let motionManager = CMMotionManager()
let queue = OperationQueue()
var gravityStr = ""
var userAccelerStr = ""
var rotationRateStr = ""
var attitudeStr = ""
var movement = ""
var manualLat: Double = 0.0
var manualLong: Double = 0.0
var heartRateVal: Double = 0.0
var prev_grav_z: Double = 0.0
var prev_acc_z: Double = 0.0
var grav_x:Double = 0.0
var grav_y:Double = 0.0
var grav_z:Double = 0.0
var acc_x:Double = 0.0
var acc_y:Double = 0.0
var acc_z:Double = 0.0
var sendOrNot:Bool = false
override func awake(withContext context: Any?) {
super.awake(withContext: context)
/**
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestLocation()
*/
// managing authorization
let healthService:HealthDataService = HealthDataService()
healthService.authorizeHealthKitAccess { (success, error) in
if success {
print("HealthKit authorization received.")
} else {
print("HealthKit authorization denied!")
if error != nil {
print("\(String(describing: error))")
}
}
}
motionManager.deviceMotionUpdateInterval = 0.5
}
/**
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let currentLoc = locations[0]
let lat = currentLoc.coordinate.latitude
let long = currentLoc.coordinate.longitude
manualLat = lat
manualLong = long
/**
let request = NSMutableURLRequest(url: NSURL(string: "http://147.46.242.219/addgps.php")! as URL)
request.httpMethod = "POST"
let postString = "a=\(lat)&b=\(long)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
}
task.resume()
*/
}
*/
/**
func locationManager(_: CLLocationManager, didFailWithError error: Error) {
let err = CLError.Code(rawValue: (error as NSError).code)!
switch err {
case .locationUnknown:
break
default:
print(err)
}
}
*/
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
motionManager.startDeviceMotionUpdates(to: queue) { (deviceMotion: CMDeviceMotion?, error: Error?) in
if error != nil {
print("Encountered error: \(error!)")
}
if deviceMotion != nil {
self.grav_x = (deviceMotion?.gravity.x)!
self.grav_y = (deviceMotion?.gravity.y)!
self.grav_z = (deviceMotion?.gravity.z)!
self.gravityStr = String(format: "grav_x: %.2f, grav_y: %.2f, grav_z: %.2f" ,
self.grav_x,
self.grav_y,
self.grav_z)
if self.prev_grav_z == 0.0 {
self.prev_grav_z = self.grav_z
self.sendOrNot = true
}
else{
if (self.grav_z - self.prev_grav_z) <= -0.25{
//print("Gravity: ",self.grav_z, self.prev_grav_z)
self.sendOrNot = true
}
else{
self.sendOrNot = false
}
self.prev_grav_z = self.grav_z
}
//self.sendData(x: self.gravityStr)
// print(self.gravityStr)
self.acc_x = (deviceMotion?.userAcceleration.x)!
self.acc_y = (deviceMotion?.userAcceleration.y)!
self.acc_z = (deviceMotion?.userAcceleration.z)!
self.userAccelerStr = String(format: "acc_x: %.2f, acc_y: %.2f, acc_z: %.2f" ,
self.acc_x,
self.acc_y,
self.acc_z)
if (self.acc_z - self.prev_acc_z) <= -0.2{
//print("Accelero_z: ",self.acc_z, self.prev_acc_z)
self.sendOrNot = true
}
else{
self.sendOrNot = false
}
self.prev_acc_z = self.acc_z
self.rotationRateStr = String(format: "rota_x: %.2f, rota_y: %.2f, rota_z: %.2f" ,
(deviceMotion?.rotationRate.x)!,
(deviceMotion?.rotationRate.y)!,
(deviceMotion?.rotationRate.z)!)
//self.sendData(x: self.rotationRateStr)
//print(self.rotationRateStr)
self.attitudeStr = String(format: "atti_roll: %.1f, atti_pitch: %.1f, atti_yaw: %.1f" ,
(deviceMotion?.attitude.roll)!,
(deviceMotion?.attitude.pitch)!,
(deviceMotion?.attitude.yaw)!)
//self.sendData(x: self.attitudeStr)
//print(self.attitudeStr)
//self.movement = self.gravityStr + self.userAccelerStr + self.rotationRateStr + self.attitudeStr
if self.sendOrNot{
//print("Falling motion detected!")
self.movement = "\(self.gravityStr), \(self.userAccelerStr), \(self.rotationRateStr), \(self.attitudeStr), \("_1")"
}
else{
self.movement = "\(self.gravityStr), \(self.userAccelerStr), \(self.rotationRateStr), \(self.attitudeStr), \("_0")"
}
//print(self.movement)
self.sendOrNot = false
}
}
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
motionManager.stopDeviceMotionUpdates()
}
/**
func sendData(x:String){
let request = NSMutableURLRequest(url: NSURL(string: "http://147.46.242.219/addgyro2.php")! as URL)
request.httpMethod = "POST"
let postString = "a=\(x)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
}
task.resume()
}
*/
/**
func getDocumentsDirectory() -> URL
{
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
func getFileUrl() -> URL
{
let filePath = getDocumentsDirectory().appendingPathComponent(filename!)
return filePath
}
func startRecording(){
let audioSession = AVAudioSession.sharedInstance()
do{
audioRecorder = try AVAudioRecorder(url: getFileUrl(),
settings: settings)
audioRecorder.delegate = self
audioRecorder.prepareToRecord()
audioRecorder.record(forDuration: 5.0)
}
catch {
finishRecording(success: false)
}
do {
try audioSession.setActive(true)
audioRecorder.record()
} catch {
}
}
func finishRecording(success: Bool) {
audioRecorder.stop()
audioRecorder = nil
if success {
print(success)
} else {
audioRecorder = nil
print("Somthing Wrong.")
}
}
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
if !flag {
finishRecording(success: false)
}
}
*/
// generate a short unique id
struct ShortCodeGenerator {
private static let base62chars = [Character]("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
private static let maxBase : UInt32 = 62
static func getCode(withBase base: UInt32 = maxBase, length: Int) -> String {
var code = ""
for _ in 0..<length {
let random = Int(arc4random_uniform(min(base, maxBase)))
code.append(base62chars[random])
}
return code
}
}
// Getting the address from longitude and latitude
func getAddressFromLatLon(pdblLatitude: String, withLongitude pdblLongitude: String) {
var center : CLLocationCoordinate2D = CLLocationCoordinate2D()
let lat: Double = Double("\(pdblLatitude)")!
//21.228124
let lon: Double = Double("\(pdblLongitude)")!
//72.833770
let ceo: CLGeocoder = CLGeocoder()
center.latitude = lat
center.longitude = lon
let loc: CLLocation = CLLocation(latitude:center.latitude, longitude: center.longitude)
ceo.reverseGeocodeLocation(loc, completionHandler:
{(placemarks, error) in
if (error != nil)
{
//print("reverse geodcode fail: \(error!.localizedDescription)")
}
let pm = placemarks! as [CLPlacemark]
if pm.count > 0 {
let pm = placemarks![0]
//print(pm.country)
//print(pm.locality)
//print(pm.subLocality)
//print(pm.thoroughfare)
//print(pm.postalCode)
//print(pm.subThoroughfare)
var addressString : String = ""
if pm.subLocality != nil {
addressString = addressString + pm.subLocality! + ", "
}
if pm.thoroughfare != nil {
addressString = addressString + pm.thoroughfare! + ", "
}
if pm.locality != nil {
addressString = addressString + pm.locality! + ", "
}
if pm.country != nil {
addressString = addressString + pm.country! + ", "
}
if pm.postalCode != nil {
addressString = addressString + pm.postalCode! + " "
}
//print(addressString)
}
})
}
#IBAction func manualBtnPressed() {
// manual reporting functionality
// generating 6 character long unique id
let uniqueId = ShortCodeGenerator.getCode(length: 6)
let txtMsg = "I am student \(uniqueId). I need help!"
print(txtMsg)
// Getting the address
if manualLat != 0.0 && manualLong != 0.0 {
var latStr = String(format:"%.2f",manualLat)
var longStr = String(format:"%.2f",manualLong)
getAddressFromLatLon(pdblLatitude: latStr, withLongitude: longStr)
let request = NSMutableURLRequest(url: NSURL(string: "http://147.46.242.219/addmanual.php")! as URL)
request.httpMethod = "POST"
let postString = "a=\(manualLat)&b=\(manualLong)&c=\(txtMsg)"
print(postString)
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
//print("error=\(error)")
return
}
//print("response = \(response)")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
//print("responseString = \(responseString)")
}
task.resume()
}
}
// when button clicked label is shown
#IBAction func btnPressed() {
if(!isRecording){
let stopTitle = NSMutableAttributedString(string: "Stop Recording")
stopTitle.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.red], range: NSMakeRange(0, stopTitle.length))
button.setAttributedTitle(stopTitle)
isRecording = true
startWorkout() //Start workout session/healthkit streaming
}else{
let exitTitle = NSMutableAttributedString(string: "Start Recording")
exitTitle.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.red], range: NSMakeRange(0, exitTitle.length))
button.setAttributedTitle(exitTitle)
isRecording = false
healthStore.end(session!)
}
}
}
extension InterfaceController: HKWorkoutSessionDelegate{
func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) {
switch toState {
case .running:
//print(date)
if let query = heartRateQuery(date){
self.currentQuery = query
healthStore.execute(query)
}
//Execute Query
case .ended:
//Stop Query
healthStore.stop(self.currentQuery!)
session = nil
default:
print("Unexpected state: \(toState)")
}
}
func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
//Do Nothing
}
func startWorkout(){
// If a workout has already been started, do nothing.
if (session != nil) {
return
}
// Configure the workout session.
let workoutConfiguration = HKWorkoutConfiguration()
workoutConfiguration.activityType = .running
workoutConfiguration.locationType = .outdoor
do {
session = try HKWorkoutSession(configuration: workoutConfiguration)
session?.delegate = self
} catch {
fatalError("Unable to create workout session")
}
healthStore.start(self.session!)
//print("Start Workout Session")
// Here audio?
/**
if audioRecorder == nil {
print("Pressed")
filename = NSUUID().uuidString+".wav"
self.startRecording()
} else {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = URL(fileURLWithPath: path)
print("Filename\(filename!)")
let pathPart = url.appendingPathComponent(filename!)
let filePath = pathPart.path
let request = NSMutableURLRequest(url: NSURL(string: "http://147.46.242.219/addsound.php")! as URL)
request.httpMethod = "POST"
let audioData = NSData(contentsOfFile: filePath)
print("Result is\(getFileUrl().path)")
print("Binary data printing")
print(audioData)
let postString = "a=\(audioData)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest){
data, response, error in
if error != nil {
print("error=\(error)")
return
}
print("response = \(response)")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print("responseString = \(responseString)")
}
task.resume()
print("Pressed2")
self.finishRecording(success: true)
}
*/
}
func heartRateQuery(_ startDate: Date) -> HKQuery? {
let datePredicate = HKQuery.predicateForSamples(withStart: startDate, end: nil, options: .strictEndDate)
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates:[datePredicate])
let heartRateQuery = HKAnchoredObjectQuery(type: hrType, predicate: predicate, anchor: nil, limit: Int(HKObjectQueryNoLimit)) { (query, sampleObjects, deletedObjects, newAnchor, error) -> Void in
//Do nothing
}
heartRateQuery.updateHandler = {(query, samples, deleteObjects, newAnchor, error) -> Void in
guard let samples = samples as? [HKQuantitySample] else {return}
DispatchQueue.main.async {
guard let sample = samples.first else { return }
// after extraction of bpm value conversion to double
let value = sample.quantity.doubleValue(for: HKUnit(from: "count/min"))
//print("Type of value is +\(type(of:value))")
let request = NSMutableURLRequest(url: NSURL(string: "http://147.46.242.219/addall.php")! as URL)
request.httpMethod = "POST"
//print(self.movement)
//let randomStr = 42.0
let postString = "gps_x=\(self.manualLat)&gps_y=\(self.manualLong)&a=\(self.movement)&hr=\(value)"
//print(postString)
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil {
//print("error=\(error)")
return
}
//print("response = \(response)")
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
//print("responseString = \(responseString)")
}
task.resume()
//print("This line is executed!")
//print(String(UInt16(value)))
}
}
return heartRateQuery
}
}
class HealthDataService {
internal let healthKitStore:HKHealthStore = HKHealthStore()
init() {}
func authorizeHealthKitAccess(_ completion: ((_ success:Bool, _ error:Error?) -> Void)!) {
let typesToShare = Set([hrType])
let typesToSave = Set([hrType])
healthKitStore.requestAuthorization(toShare: typesToShare, read: typesToSave) { (success, error) in
completion(success, error)
}
}
}
After I tried running your project in Xcode on Apple Watch, it crashed and the console said Could not cast value of type 'BullyingDetection_WatchKit_Extension.LocationOutside' (0x92ca0) to 'CLLocationManagerDelegate' (0x6b433f84).
On line 20 of your LocationOutside class, locationManager.delegate = (self as! CLLocationManagerDelegate) will have to be locationManager.delegate = self and the class will need to conform to the CLLocationManagerManagerDelegate protocol which also requires inheriting from NSObject:
class LocationOutside: NSObject, CLLocationManagerDelegate {
}
This should lead you in the right direction.
It may help to also read about delegation here https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID276.
I am trying to show multiple locations which saved in Mysql using the code below. The data is loading but I have no idea how to show multiple locations depending on latitude and longitude.
Mysql is connected to application via PHP file.
Here is my code, the part which I called from NSObject:
func downloadItems() {
// the download function
// return the nsuserdefaults which hold the lati and longi from the notification table
UserDefaults.standard.string(forKey: "test");
let myUrl = UserDefaults.standard.string(forKey: "test");
let urlPath: String = myUrl!
let url: URL = URL(string: urlPath)!
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
let task = defaultSession.dataTask(with: url) { (data, response, error) in
if error != nil {
print("Failed to download data")
}else {
print("Data downloaded")
self.parseJSON(data!)
}
}
task.resume()
}
func parseJSON(_ data:Data) {
var jsonResult = NSArray()
do{
jsonResult = try JSONSerialization.jsonObject(with: data, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
} catch let error as NSError {
print(error)
}
var jsonElement = NSDictionary()
let locations = NSMutableArray()
for i in 0 ..< jsonResult.count
{
jsonElement = jsonResult[i] as! NSDictionary
let location = LocationModel()
//the following insures none of the JsonElement values are nil through optional binding
if let evIdL = jsonElement["id"] as? String,
let evUserNameL = jsonElement["username"] as? String,
let evNotikindL = jsonElement["notikind"] as? String,
let evLatiL = jsonElement["lati"] as? String,
let evLongiL = jsonElement["longi"] as? String,
let evLocatL = jsonElement["locat"] as? String,
let evTimedateL = jsonElement["timedate"] as? String,
let evDistanceL = jsonElement["distance"] as? String
{
location.evId = evIdL
location.evUsername = evUserNameL
location.evNotikind = evNotikindL
location.evLati = evLatiL
location.evLongi = evLongiL
location.evLocat = evDistanceL
location.evTimedate = evTimedateL
location.evDisatnce = evDistanceL
location.evLocat = evLocatL
}
locations.add(location)
}
DispatchQueue.main.async(execute: { () -> Void in
self.delegate.itemsDownloaded(items: locations)
})
}
}
I have no idea how to show few location on map.
try this code....
var locations = NSMutableArray()
var mapView = GMSMapView()
for i in 0..< location.count{
let obj = location[i]
lat = obj["lati"] as? Double
lng = obj["longi"] as? Double
let markerPoint = GMSMarker()
markerPoint.position = CLLocationCoordinate2D(latitude: lat!, longitude: lng!)
markerPoint.iconView = self.avtarImage() // Your image name
markerPoint.map = mapView // your mapview object name
markerPoint.zIndex = Int32(i)
markerPoint.infoWindowAnchor = CGPoint(x: 0, y: 0)
markerPoint.accessibilityLabel = String(format: "%d", i)
}
I want show path between destination and source on google map. I am google direction api's getting route between of co-ordinates , I am getting response and set on google map but not showing on map . My code is
func getPolylineRoute(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D){
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(source.latitude),\(source.longitude)&destination=\(destination.latitude),\(destination.longitude)&sensor=true&mode=driving&key=AIzaSyAyU5txJ86b25-_l0DW-IldSKGGYqQJn3M")!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
DispatchQueue.main.async {
if error != nil {
print(error!.localizedDescription)
AppManager.dissmissHud()
}
else {
do {
if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{
guard let routes = json["routes"] as? NSArray else {
DispatchQueue.main.async {
AppManager.dissmissHud()
}
return
}
if (routes.count > 0) {
let overview_polyline = routes[0] as? NSDictionary
let dictPolyline = overview_polyline?["overview_polyline"] as? NSDictionary
let points = dictPolyline?.object(forKey: "points") as? String
self.showPath(polyStr: points!)
DispatchQueue.main.async {
AppManager.dissmissHud()
let bounds = GMSCoordinateBounds(coordinate: source, coordinate: destination)
let update = GMSCameraUpdate.fit(bounds, with: UIEdgeInsetsMake(75, 20, 20, 20))
self.vwMap!.moveCamera(update)
}
}
else {
DispatchQueue.main.async {
AppManager.dissmissHud()
}
}
}
}
catch {
print("error in JSONSerialization")
DispatchQueue.main.async {
AppManager.dissmissHud()
}
}
}
}
})
task.resume()
}
func drawPlyLineOnMap() {
let source : CLLocationCoordinate2D = CLLocationCoordinate2DMake(Double((model?.fromAddressLatitude)!), Double((model?.fromAddressLongtitude)!))
let destination : CLLocationCoordinate2D = CLLocationCoordinate2DMake(Double((model?.toAddressLatitude)!), Double((model?.toAddressLongtitude)!))
self.vwMap.clear()
//Source pin
let marker = GMSMarker()
let markerImage = UIImage(named: "from_pin")!.withRenderingMode(.alwaysOriginal)
let markerView = UIImageView(image: markerImage)
marker.position = source
marker.iconView = markerView
//marker.userData = dict
marker.map = vwMap
//Destination pin
let markerTo = GMSMarker()
let markerImageTo = UIImage(named: "to_red_pin")!.withRenderingMode(.alwaysOriginal)
let markerViewTo = UIImageView(image: markerImageTo)
markerTo.position = destination
// marker.userData = dict
markerTo.iconView = markerViewTo
markerTo.map = vwMap
var arrAdTemp:[AddressTableModel] = []
arrAdTemp.append(contentsOf: arrAddresses)
arrAdTemp.removeLast()
arrAdTemp.removeFirst()
for obj in arrAdTemp {
print(obj.strLatitude)
print(obj.strLongtitude)
let stopOver : CLLocationCoordinate2D = CLLocationCoordinate2DMake(obj.strLatitude, obj.strLongtitude)
let markerStop = GMSMarker()
let markerImageStop = UIImage(named: "to_red_pin")!.withRenderingMode(.alwaysOriginal)
let markerViewStop = UIImageView(image: markerImageStop)
markerStop.position = stopOver
//marker.userData = dict
markerStop.iconView = markerViewStop
markerStop.map = vwMap
}
self.getPolylineRoute(from: source, to: destination)
}
func showPath(polyStr :String){
let path = GMSPath(fromEncodedPath: polyStr)
let polyline = GMSPolyline(path: path)
polyline.strokeWidth = 3.0
polyline.strokeColor = UIColor.black
polyline.map = vwMap // Your map view
}
I have tried lot of answer give below but not working for me. Please help me.
1st answer tried
2nd answer tried
3rd answer tried
you are setting wrong bounds so it is not showing on your map . I have tried your code it is working fine . Please change your bounds area as (0,0,0,0)
func getPolylineRoute(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D){
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(source.latitude),\(source.longitude)&destination=\(destination.latitude),\(destination.longitude)&sensor=true&mode=driving&key=AIzaSyAyU5txJ86b25-_l0DW-IldSKGGYqQJn3M")!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
DispatchQueue.main.async {
if error != nil {
print(error!.localizedDescription)
AppManager.dissmissHud()
}
else {
do {
if let json : [String:Any] = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]{
guard let routes = json["routes"] as? NSArray else {
DispatchQueue.main.async {
AppManager.dissmissHud()
}
return
}
if (routes.count > 0) {
let overview_polyline = routes[0] as? NSDictionary
let dictPolyline = overview_polyline?["overview_polyline"] as? NSDictionary
let points = dictPolyline?.object(forKey: "points") as? String
self.showPath(polyStr: points!)
DispatchQueue.main.async {
AppManager.dissmissHud()
let bounds = GMSCoordinateBounds(coordinate: source, coordinate: destination)
//below bounds change as 0 check it on full screen
let update = GMSCameraUpdate.fit(bounds, with: UIEdgeInsetsMake(0, 0, 0, 0))
self.vwMap!.moveCamera(update)
}
}
else {
DispatchQueue.main.async {
AppManager.dissmissHud()
}
}
}
}
catch {
print("error in JSONSerialization")
DispatchQueue.main.async {
AppManager.dissmissHud()
}
}
}
}
})
task.resume()
}
I did the same using this code have a look.
{let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(self.currentLocation.coordinate.latitude),\(self.currentLocation.coordinate.longitude)&destination=\(33.6165),\(73.0962)&key=yourKey")
let request = URLRequest(url: url!)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let task = session.dataTask(with: request, completionHandler: {(data, response, error) in
// notice that I can omit the types of data, response and error
do{
let json = JSON(data!)
let errornum = json["error"]
if (errornum == true){
}else{
let routes = json["routes"].array
if routes != nil && (routes?.count)! > 0{
let overViewPolyLine = routes![0]["overview_polyline"]["points"].string
let dict = routes![0].dictionaryValue
let distance = dict["legs"]?[0]["distance"]
_ = distance?["text"].stringValue
let duaration = dict["legs"]?[0]["duration"]
_ = duaration?["text"].stringValue
//dict["legs"]?["distance"]["text"].stringValue
print(overViewPolyLine!)
if overViewPolyLine != nil{
DispatchQueue.main.async() {
self.addPolyLineWithEncodedStringInMap(encodedString: overViewPolyLine!)
}
}
}
}
and then
{
func addPolyLineWithEncodedStringInMap(encodedString: String) {
let path = GMSPath(fromEncodedPath: encodedString)!
let polyLine = GMSPolyline(path: path)
polyLine.strokeWidth = 5
polyLine.strokeColor = UIColor.yellow
polyLine.map = self.googleMapsView
let center = CLLocationCoordinate2D(latitude: 33.6165, longitude: 73.0962)
let marker = GMSMarker(position: center)
marker.map = self.googleMapsView
}
func decodePolyline(encodedString: String){
let polyline = Polyline(encodedPolyline: encodedString)
let decodedCoordinates: [CLLocationCoordinate2D]? = polyline.coordinates
for coordinate in decodedCoordinates! {
let marker = GMSMarker(position: coordinate)
marker.icon = UIImage(named: "mapPin")
marker.map = self.googleMapsView
}
}
What I want to do is pass the user location to complete my JSON URL. But the way I do it, it prints "optional(coordinate)" and I just want the coordinate wihtout the optional. I tried to erase ? but it would mark error at the moment to build.
I tried to get the user location in the func locationManager and I try to use them in the func loadGas. Any help could be of use.
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController,MKMapViewDelegate, CLLocationManagerDelegate,UICollectionViewDelegate, UICollectionViewDataSource {
let manager = CLLocationManager()
public let sMAGNA = "magna"
public let sPREMIUM = "premium"
public let sDIESEL = "diesel"
public let MIN_TIME: CLong = 400
private let MIN_DISTANCE: Float = 1000
private var ubicaciones_selected: [Ubicacion] = []
private var ubicaciones_magna: [Ubicacion] = []
private var ubicaciones_premium: [Ubicacion] = []
private var ubicaciones_diesel: [Ubicacion] = []
private let REQUEST_LOCATION = 1
private var latlon: String = ""
private var mType: String = "magna"
var ubicaciones:[Ubicacion] = []
var Ubigaspin = MKPointAnnotation()
#IBAction func MapType(_ sender: Any) {
if mapa.mapType == MKMapType.standard{
mapa.mapType = MKMapType.satellite
} else { mapa.mapType = MKMapType.standard
}
}
#IBOutlet var mapa: MKMapView!
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
print(myLocation)
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
mapa.setRegion(region, animated: true)
self.mapa.showsUserLocation = true
manager.stopUpdatingLocation()
}
override func viewDidLoad() {
super.viewDidLoad()
//con esto obtendremos la ubicacion del usuario
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
mapa.showsUserLocation = true
manager.startUpdatingLocation()
//se cargan los pines y las gasolinas
loadGas(tipo: mType)
}
func loadGas(tipo:String){
mType = tipo
var ubicaciones:[Ubicacion] = []
switch tipo {
case sMAGNA:
ubicaciones = ubicaciones_magna
case sPREMIUM:
ubicaciones = ubicaciones_premium
case sDIESEL:
ubicaciones = ubicaciones_diesel
default:
ubicaciones = ubicaciones_magna
}
if ubicaciones.count == 0 {
let lat = String(describing: manager.location?.coordinate.latitude)
let long = String(describing: manager.location?.coordinate.longitude)
let url = URL(string: "http://192.241.214.56/api/ubicacion/?format=json&sub="+lat+","+long)
print (url)
// let url = URL(string: "http://192.241.214.56/api/ubicacion/?format=json&sub=29.08919%2C-110.96133")
// let url = URL(string: "http://192.241.214.56/api/"+tipo+"/?format=json")
URLSession.shared.dataTask(with: url!, completionHandler: {
(data, response, error) in
if(error != nil){
print("error")
}else{
do{
let ubicaciones_json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [[String : AnyObject]]
for ubicacion in ubicaciones_json{
let nombre:String = ubicacion["nombre"] as! String
let direccion:String = ubicacion["direccion"] as! String
let precio_magna:Float = ubicacion["precio_magna"] as! Float
let precio_premium:Float = ubicacion["precio_premium"] as! Float
let precio_diesel:Float = ubicacion["precio_diesel"] as! Float
let ubicacion:String = ubicacion["ubicacion"] as! String
let p = Ubicacion()
p.ubicacion = ubicacion
p.setLatLng()
p.nombre = nombre
p.direccion = direccion
p.precio_magna = precio_magna
p.precio_premium = precio_premium
p.precio_diesel = precio_diesel
ubicaciones.append(p)
}
self.ubicaciones = ubicaciones
OperationQueue.main.addOperation({
self.updatePins(ubicaciones: ubicaciones)
})
}catch let error as NSError{
print(error)
}
}
}).resume()
}else{
self.ubicaciones = ubicaciones
self.updatePins(ubicaciones: ubicaciones)
}
}
Instead of
let lat = String(describing: manager.location?.coordinate.latitude)
you should do something like this:
guard let location = manager.location else {
return
}
let lat = String(format: "%f", location.coordinate.latitude)
Im New to Swift and I'm Integrating PayUmoney IOS SDK in swift, Im getting trouble When I'm doing in live its showing hash mismatch (Hash mismatch1) If I'm doing in test its showing invalid merchant key (Invalid key) I struck here from 2 weeks Did so many things and didn't get any solution for this can any one help it would be awesome. Below is my code, Thank you in Advance.
var params : PUMRequestParams = PUMRequestParams.shared()
var utils : Utils = Utils()
params.environment = PUMEnvironment.test;
params.firstname = txtFldName.text;
params.key = "bZf4AOjj";
params.merchantid = "5745303";
params.logo_url = "";
params.productinfo = "Product Info";
params.email = txtFldEmail.text;
params.phone = "";
params.surl = "https://www.payumoney.com/mobileapp/payumoney/success.php";
params.furl = "https://www.payumoney.com/mobileapp/payumoney/failure.php";
if(params.environment == PUMEnvironment.test){
generateHashForProdAndNavigateToSDK()
}
else{
calculateHashFromServer()
}
// assign delegate for payment callback.
params.delegate = self;
}
func generateHashForProdAndNavigateToSDK() -> Void {
let txnid = params.txnid!
let hashSequence : NSString = "\(params.key)|\(txnid)|\(params.amount)|\(params.productinfo)|\(params.firstname)|\(params.email)|||||||||||2uIsGhXWVw" as NSString
let data :NSString = utils.createSHA512(hashSequence as String!) as NSString
params.hashValue = data as String!;
startPaymentFlow();
}
// MARK:HASH CALCULATION
func prepareHashBody()->NSString{
return "SHA-512key=\(params.key!)&amount=\(params.amount!)&txnid=\(params.txnid!)&productinfo=\(params.productinfo!)&email=\(params.email!)&firstname=\(params.firstname!)" as NSString;
}
func calculateHashFromServer(){
let config = URLSessionConfiguration.default // Session Configuration
let session = URLSession(configuration: config) // Load configuration into Session
let url = URL(string: "https://test.payumoney.com/payment/op/v1/calculateHashForTest")!
var request = URLRequest(url: url)
request.httpBody = prepareHashBody().data(using: String.Encoding.utf8.rawValue)
request.httpMethod = "POST"
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
} else {
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]{
print(json)
let status : NSNumber = json["status"] as! NSNumber
if(status.intValue == 0)
{
self.params.hashValue = json["result"] as! String!
OperationQueue.main.addOperation {
self.startPaymentFlow()
}
}
else{
OperationQueue.main.addOperation {
self.showAlertViewWithTitle(title: "Message", message: json["message"] as! String)
}
}
}
} catch {
print("error in JSONSerialization")
}
}
})
task.resume()
}
Hello Vinny do with webview its working for me. Before I also used this PayUmoney IOS SDK but faced so many problems so based on objective-c I did this so I think its useful to you. create a weak var webview and create class UIwebviewdelegate
class PayumoneyViewController: UIViewController, UIWebViewDelegate, UIAlertViewDelegate {
#IBOutlet weak var Webview: UIWebView!
and for test use below credentials
//test
var merchantKey = "40747T"
var salt = "ur salt"
var PayUBaseUrl = "https://test.payu.in"
For live
//Production
var merchantKey = “xxxxxx”
var salt = “xxxxx”
var PayUBaseUrl = "https://secure.payu.in"
let productInfo = “Myapp” //It can be Project name or anything else
let firstName = “Santoshi” //Details of user whose is purchasing order
let email = “santoshi#app.com" //Details of user whose is purchasing order
let phone = "xxxxxxxxx" //Details of user whose is purchasing order
let sUrl = "www.google.com" //By this URL we match whether payment got success or failure
let fUrl = "www.google.com" //By this URL we match whether payment got success or failure
let service_provider = "payu_paisa"
var txnid1: String! = "" //Its an unique id which can give order a specific order number.
let totalPriceAmount = "1.0"
Above viewdidload do like this
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
initPayment()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
}
In viewdidload do like this
override func viewDidLoad() {
super.viewDidLoad()
Webview.delegate = self
// Do any additional setup after loading the view.
}
Create payment and Generate Hash key
func initPayment() {
txnid1 = “Myapp\(String(Int(NSDate().timeIntervalSince1970)))"
//Generating Hash Key
let hashValue = String.localizedStringWithFormat("%#|%#|%#|%#|%#|%#|||||||||||%#",merchantKey,txnid1,totalPriceAmount,productInfo,firstName,email,salt)
let hash = self.sha1(string: hashValue)
let postStr = "txnid="+txnid1+"&key="+merchantKey+"&amount="+totalPriceAmount+"&productinfo="+productInfo+"&firstname="+firstName+"&email="+email+"&phone="+phone+"&surl="+sUrl+"&furl="+fUrl+"&hash="+hash+"&service_provider="+service_provider
let url = NSURL(string: String.localizedStringWithFormat("%#/_payment", PayUBaseUrl))
let request = NSMutableURLRequest(url: url! as URL)
do {
let postLength = String.localizedStringWithFormat("%lu",postStr.characters.count)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Current-Type")
request.setValue(postLength, forHTTPHeaderField: "Content-Length")
request.httpBody = postStr.data(using: String.Encoding.utf8)
Webview.loadRequest(request as URLRequest)
}
catch let error as NSError
{
print(error)
}
}
Finally Do this
func sha1(string:String) -> String {
let cstr = string.cString(using: String.Encoding.utf8)
let data = NSData(bytes: cstr, length: string.characters.count)
var digest = [UInt8](repeating: 0, count:Int(CC_SHA512_DIGEST_LENGTH))
CC_SHA512(data.bytes, CC_LONG(data.length), &digest)
let hexBytes = digest.map { String(format: "%02x", $0) }
return hexBytes.joined(separator: "")
}
func webViewDidFinishLoad(_ webView: UIWebView) {
let requestURL = self.Webview.request?.url
let requestString:String = (requestURL?.absoluteString)!
if requestString.contains("https://www.payumoney.com/mobileapp/payumoney/success.php") {
print("success payment done")
}else if requestString.contains("https://www.payumoney.com/mobileapp/payumoney/failure.php") {
print("payment failure")
}
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
let requestURL = self.Webview.request?.url
print("WebView failed loading with requestURL: \(requestURL) with error: \(error.localizedDescription) & error code: \(error)")
if error._code == -1009 || error._code == -1003 {
showAlertView(userMessage: "Please check your internet connection!")
}else if error._code == -1001 {
showAlertView(userMessage: "The request timed out.")
}
}
func showAlertView(userMessage:String){
}
I have Faced Same problem and i have got solution of this problem.
In my code this line generate optional values --> let hashSequence : NSString = "(params.key!)|(txnid)|(params.amount!)|(params.productinfo!)|(params.firstname!)|(params.email!)|||||||||||(params.merchantid!)" as NSString
remove optional from the values.