Sound on Push notification - swift2

Helo friends
I created a code to push nofication, but the notification are silient, I need to use sound,
On this line I specify the types:
let notificationTypes = UIUserNotificationType.Alert
But dont work.
Another dount, How can I use Badge to add number in app icon?
this is my code:
func setupNotificationSettings() {
let notificationSettings: UIUserNotificationSettings! = UIApplication.sharedApplication().currentUserNotificationSettings()
if (notificationSettings.types == UIUserNotificationType.None){
let notificationTypes = UIUserNotificationType.Alert
let modifyListAction = UIMutableUserNotificationAction()
modifyListAction.identifier = "editList"
modifyListAction.title = "Edit list"
modifyListAction.activationMode = UIUserNotificationActivationMode.Foreground
modifyListAction.destructive = false
modifyListAction.authenticationRequired = true
let trashAction = UIMutableUserNotificationAction()
trashAction.identifier = "trashAction"
trashAction.title = "Delete list"
trashAction.activationMode = UIUserNotificationActivationMode.Background
trashAction.destructive = true
trashAction.authenticationRequired = true
let actionsArray = NSArray(objects: modifyListAction, trashAction)
let actionsArrayMinimal = NSArray(objects: trashAction, modifyListAction)
/
let shoppingListReminderCategory = UIMutableUserNotificationCategory()
shoppingListReminderCategory.identifier = "shoppingListReminderCategory"
shoppingListReminderCategory.setActions(actionsArray as? [UIUserNotificationAction], forContext: UIUserNotificationActionContext.Default)
shoppingListReminderCategory.setActions(actionsArrayMinimal as? [UIUserNotificationAction], forContext: UIUserNotificationActionContext.Minimal)
let categoriesForSettings = NSSet(objects: shoppingListReminderCategory)
/
let newNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categoriesForSettings as? Set<UIUserNotificationCategory>)
UIApplication.sharedApplication().registerUserNotificationSettings(newNotificationSettings)
}
}
func pushNotificationTest(){
let localNotification = UILocalNotification()
localNotification .fireDate = fixNotificationDate(datePicker.date) //usar com datepicker
localNotification.alertBody = "Test"
localNotification.alertAction = "Test test test"
localNotification.category = "shoppingListReminderCategory"
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
}

You didn't request enough permissions. You only requested .Alert, but .Sound and .Badge should all be included. Change:
let notificationTypes = UIUserNotificationType.Alert
to:
let notificationTypes: UIUserNotificationType = [.Alert, .Sound, .Badge]
To add a badge number, use:
localNotification.applicationIconBadgeNumber = 1

Related

fatal : Array index out of range

Every child has a pick up point location consists of latitude and longitude that i fetch from sqlite database. I have childIdArray which is array of childID's. I want to calculate the estimate time(ETA) from current location of their respective drivers location i fetch from getCurrentLocationOfRespectiveDrivers() method with pickUp point of children that i fetch from sqlite database in form of array of latitude and longitude.
but i get error
fatal error: Array index out of range
in getCurrentLocationOfRespectiveDrivers() method.
Any help would be highly appreciated.. thanks in advance
var etaArray : [String] = []
var estimatedTime : String?
var latitudeArray : [Double] = []
var longitudeArray : [Double] = []
override func viewDidLoad() {
super.viewDidLoad()
let rs = ModelManager.sharedInstance.fetchingPickUpAnnotationsArray(ChildDetailsVC.parentID)
latitudeArray = rs.latPickUp
longitudeArray = rs.longPickUp
print("pickUpLatitudeArray = \(latitudeArray)")
print("pickUpLongitudeArray = \(longitudeArray)")
let result = ModelManager.sharedInstance.fetchingChildren( ChildDetailsVC.parentID)
self.childNameArray = result.childNames
self.childImageArray = result.childImages
self.childIDArray = result.chidIDs
self.childDriverArray = result.childDrivers
getCurrentLocationOfRespectiveDrivers()
for (var i = 0; i < childIDArray.count; i++)
{
etaArray.append("")
}
}
func getCurrentLocationOfRespectiveDrivers()
{
for( var i = 0 ; i < latitudeArray.count ; i++)
{
let url:NSURL = NSURL(string:"http://development.ssntpl.com/gogo_app/api.php?action=getDriverCurrentLocation")!
let request = NSMutableURLRequest(URL:url)
request.HTTPMethod = "POST"
let post:NSString = "child_id=\(childIDArray)"
request.HTTPBody = post.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{
data, response, error in
if error != nil
{
print("error is \(error)")
return;
}
do
{
let myJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = myJSON
{
let Status = parseJSON["status"] as! Int
let Code = parseJSON["code"] as! Int
if (Status == 1 && Code == 200)
{
let Result = parseJSON["result"] as! NSArray
self.etaArray.removeAll()
//here i get the crash fatal error: Array index out of range
let latitudePickUp = self.latitudeArray[i]
let longitudePickUp = self.longitudeArray[i]
let CoordinatePickUp = CLLocation(latitude: latitudePickUp, longitude: longitudePickUp)
for res in Result
{
self.estimatedTime = ""
if (res["exists"] as! Int == 1)
{
let lastLatitude = res["latitude"] as! CLLocationDegrees
let lastLongitude = res["longitude"] as! CLLocationDegrees
let Location : CLLocation = CLLocation(latitude: lastLatitude, longitude: lastLongitude)
let meters:CLLocationDistance = Location.distanceFromLocation(CoordinatePickUp)
print(meters)
let ID = res["child_id"] as! String
let time = round(meters/40000 * 60)
self.estimatedTime = String(time)
self.etaArray.append(self.estimatedTime!)
}
else
{
self.etaArray.append("")
}
}
}
else
{
}
}
}
catch
{
print(error)
}
}
//executing the task
task.resume()
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
}

Could not cast value of type '__NSCFNumber' (0x10e59f3c0) to 'NSString' (0x10dba7ad8) swift 3

I've been tying to figure out this one for a few days now... Here is my original code:
if let ratingDic = dictionary["rating"] as? [String: Any],
let ratingId = ratingDic["id"] {
searchResult.ratingID = ratingId as! String
}
Here is my api:
"amount" = "50.00";
"rating" = {
"name" = "Platinum";
"id" = 5
I'm pretty sure I need to use "valueForKey" so here is my updated code:
if let ratingDic = dictionary["rating"] as? [String: Any],
//let ratingId = ratingDic["id"] {
let ratingId = [ratingDic.valueForKey("id")!] {
searchResult.ratingID = ratingId as! Number
}
However now I receive the "Value for type String:Any has no member "valueForKey"
Never mind, I was forgetting to change the actual variable to a "Double" or number
var ratingID = 0.0
instead of
var ratingID = ""
and the code now reads
if let ratingDic = dictionary["rating"] as? [String: Any],
let ratingId = ratingDic["id"] {
searchResult.ratingID = ratingId as! Double
}

Swift 2 - User's Current Location is inside MKPolygon

I am trying to check if the user's current location is inside the MKPolygon. I have created the following function but it returns false for all my test cases. Is there something I might be doing wrong?
func isCorrectRegion(coordinates: Array<JSON>, userLocation: CLLocationCoordinate2D) -> Bool {
var newCoordinates: [CLLocationCoordinate2D] = []
var mapPoints: [MKMapPoint] = []
for(a):(JSON) in coordinates {
let lat = a.arrayValue[1].double
let long = a.arrayValue[0].double
let location = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
newCoordinates.append(location)
}
for b in newCoordinates {
let c: MKMapPoint = MKMapPointForCoordinate(b)
mapPoints.append(c)
}
let polygon: MKPolygon = MKPolygon(points: &mapPoints, count: mapPoints.count)
let polyRender: MKPolygonRenderer = MKPolygonRenderer(polygon: polygon)
polyRender.invalidatePath()
let target: MKMapPoint = MKMapPointForCoordinate(userLocation)
let cgTarget: CGPoint = CGPoint(x: target.x, y: target.y)
let isWithin = CGPathContainsPoint(polyRender.path, nil, cgTarget, false)
return isWithin
}
Finally figured it out after trying a few different things. Hope this helps others:
func isCorrectRegion(coordinates: Array<JSON>, userLocation: CLLocationCoordinate2D) -> Bool {
var newCoordinates: [CLLocationCoordinate2D] = []
var mapPoints: [MKMapPoint] = []
let mpr: CGMutablePathRef = CGPathCreateMutable()
for(a):(JSON) in coordinates {
let lat = a.arrayValue[1].double
let long = a.arrayValue[0].double
let location = CLLocationCoordinate2D(latitude: lat!, longitude: long!)
newCoordinates.append(location)
}
for b in newCoordinates {
let c: MKMapPoint = MKMapPointForCoordinate(b)
mapPoints.append(c)
}
for var p = 0; p<mapPoints.count; p++ {
if p == 0 {
CGPathMoveToPoint(mpr, nil, CGFloat(mapPoints[p].x), CGFloat(mapPoints[p].y))
} else {
CGPathAddLineToPoint(mpr, nil, CGFloat(mapPoints[p].x), CGFloat(mapPoints[p].y))
}
}
let target: MKMapPoint = MKMapPointForCoordinate(userLocation)
let cgTarget: CGPoint = CGPoint(x: target.x, y: target.y)
let isWithin = CGPathContainsPoint(mpr, nil, cgTarget, false)
return isWithin
}

how to place two images on two different markers in mapKit using swift

I want to change marker image in my MKPointAnnotation() and I have successfully changed my image but problem is that I have 2 marker points and I want to place ignitionon.png on point one and ignitionof.png on point two and my logic place ignitionon.png on both the points.
Code
if(self.doubelLocation) {
var pointOff = CLLocationCoordinate2D()
var pointOn = CLLocationCoordinate2D()
if(self.dateTime.count > 0) {
for(var i : Int = 0 ; i < self.dateTime.count ; i++) {
// print("Real status = \(self.dateTime[i])")
var fixTime = self.dateTime[i]
if(fixTime == self.dateTimeTwo) {
pointOff = CLLocationCoordinate2DMake(self.latt[i], self.lngg[i]);
print("pointOff = \(pointOff)")
//points.append(pointOf)
}
if(fixTime == self.dateTimeOne){
pointOn = CLLocationCoordinate2DMake(self.latt[i], self.lngg[i]);
print("pointOn = \(pointOn)")
//points.append(pointOf)
}
}
var points: [CLLocationCoordinate2D]
points = [pointOn, pointOff]
dispatch_async(dispatch_get_main_queue(), {
let geodesic = MKGeodesicPolyline(coordinates: &points[0], count: 2)
self.theMapView.addOverlay(geodesic)
let latDelta:CLLocationDegrees = 0.03
let lnggDelta:CLLocationDegrees = 0.03
UIView.animateWithDuration(1.5, animations: { () -> Void in
let span = MKCoordinateSpanMake(latDelta, lnggDelta)
let region1 = MKCoordinateRegion(center: points[0], span: span)
self.theMapView.setRegion(region1, animated: true)
self.ActivityIndicator.stopAnimating()
for(var i : Int = 0 ;i < points.count; i++){
var st = self.reportText[i]
// let theMarker = MKPointAnnotation()
//how to change marker color
//https://stackoverflow.com/questions/33532883/add-different-pin-color-with-mapkit-in-swift-2-1
let theMarker = MKPointAnnotation()
theMarker.coordinate = points[i]
// if(st == "IGNITION ON"){
if(i == 0){
theMarker.title = "Status : IGNITION OFF"
theMarker.subtitle = "\(self.locationOff)"
// theMarker.subtitle = "Date = , Reg#: "
self.theMapView.addAnnotation(theMarker)
let anView1:MKAnnotationView = MKAnnotationView()
anView1.annotation = theMarker
anView1.image = UIImage(named:"ignitionof")
anView1.canShowCallout = true
anView1.enabled = true
}
if(i == 1){
// theMarker = UIColor.greenColor()
theMarker.title = "Status : IGNITION ON"
theMarker.subtitle = "\(self.locationOn)"
// theMarker.subtitle = "Date = , Reg#: "
self.theMapView.addAnnotation(theMarker)
//how to change image of marker
//https://stackoverflow.com/questions/24467408/swift-add-mkannotationview-to-mkmapview
let anView:MKAnnotationView = MKAnnotationView()
anView.annotation = theMarker
anView.image = UIImage(named:"ignitionon")
anView.canShowCallout = true
anView.enabled = true
}
// }
}
})
})
}
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if (annotation is MKUserLocation) {
//if annotation is not an MKPointAnnotation (eg. MKUserLocation),
//return nil so map draws default view for it (eg. blue dot)...
return nil
}
let reuseId = "test"
var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
anView!.image = UIImage(named:"ignitionon")
anView!.canShowCallout = true
}
var anView1 = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView1 == nil {
anView1 = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
anView1!.image = UIImage(named:"ignitionof")
anView1!.canShowCallout = true
}
else {
//we are re-using a view, update its annotation reference...
anView!.annotation = annotation
}
return anView
}
I am following this Link:
Swift - Add MKAnnotationView To MKMapView
It's not the best way to handle multiple marker with different metadata.
You can't use mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) two times or more because in viewForAnnotation it is for only 1 view for each Point you have added in the stack.
Create a sub-class of MKPointAnnotation:
class CustomPointAnnotation: MKPointAnnotation {
var tag: String!
}
Create a Dictionary with all images:
var imagesPath : ["tag_1": "image_1.png", "tag_2": "image_2.jpg"]
Now in the delegate func, check Simply
if !(annotation is CustomPointAnnotation) {
return nil
}
and Handle the only one View you have:
let reuseId = "test"
var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
var customannotation = annotation as! CustomPointAnnotation
anView!.image = UIImage(named: imagesPath(customannotation.tag))
anView!.canShowCallout = true
}
An example to add a new Custom point is:
let aPoint = CustomPointAnnotation()
aPoint.coordinate = CLLocationCoordinate2DMake(40.730872, -73.003066)
aPoint.title = "Info1"
aPoint.subtitle = "Subtitle"
aPoint.tag = "tag_1"
mapView.addAnnotation(aPoint)

Returning from a function in a closure

I need to get an array of events for a certain day in Swift. Because EKEventStore.requestAccessToEntityType is run asynchronously, I am using dispatch_group_notify to wait for the completion handler of EKEventStore.requestAccessToEntityType to complete so I can do something with it then return it. But I can't return from the function inside the closure I pass to dispatch_group_notify because it tries the return from the closure, not the function. Here is my code
class func eventsOn(date: NSDate) -> [Event] {
var events = [Event]()
var ekEvents = [EKEvent]()
var dispatch_group = dispatch_group_create()
dispatch_group_enter(dispatch_group)
Event.eventStore.requestAccessToEntityType(EKEntityTypeEvent, completion: {
gotAccess, error in
let cal = NSCalendar.currentCalendar()
var comps = cal.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: date)
let aFewHoursAgo = NSDateComponents()
aFewHoursAgo.hour = -5
var daStartDate = cal.dateFromComponents(comps)!
daStartDate = cal.dateByAddingComponents(aFewHoursAgo, toDate: daStartDate, options: .allZeros)!
var aDay = NSDateComponents()
aDay.day = 1
var daEndDate = cal.dateByAddingComponents(aDay, toDate: daStartDate, options: .allZeros)!
daEndDate = daEndDate.dateByAddingTimeInterval(-1)!
let p = Event.eventStore.predicateForEventsWithStartDate(daStartDate, endDate: daEndDate, calendars: [Event.eventStore.defaultCalendarForNewEvents])
let tmp = Event.eventStore.eventsMatchingPredicate(p) as [EKEvent]?
if let _ = tmp {
ekEvents = tmp!
}
dispatch_group_leave(dispatch_group)
})
let queue = dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)
dispatch_group_notify(dispatch_group, queue) {
println(ekEvents)
let ekEventId = Expression<String>("ekEventId")
let eventId = Expression<Int>("id")
for ekEvent in ekEvents {
let daEventId = Event.db["events"].filter(ekEventId == ekEvent.eventIdentifier).select(eventId).first![eventId]
events.append(Event.eventWithId(daEventId)!)
}
return events
}
}
So where I put return events inside of the block I passed to dispatch_group_notify it tries to return from the closure, but I'd like to return from the function. How can I do this?

Resources