Post

Replies

Boosts

Views

Activity

Fragment large size data sent and received using NSKeyedArchiver.archivedData in GameCenter
Trying to send and receive data in the GameCenter environment using the following methods: func sendData(dictionaryWithData dictionary: Dictionary<String, Any>,toPeer targetPeers: [GKPlayer]) { guard let match = self.match else { return } do { let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false) try match.send(dataToSend, to: targetPeers, dataMode: .reliable) } catch { #if DEBUG print("CONNECTION MANAGER SEND DATA ERROR") #endif } } public func match(_ theMatch: GKMatch,didReceive data: Data,forRecipient recipient: GKPlayer,fromRemotePlayer player: GKPlayer) { if match != theMatch { return } DispatchQueue.main.async { do { guard let message = NSDictionary.unsecureUnarchived(from: data) as? Dictionary<String, Any> else {return} ... <CODE> ... } ///Source: https://stackoverflow.com/questions/51487622/unarchive-array-with-nskeyedunarchiver-unarchivedobjectofclassfrom static func unsecureUnarchived(from data: Data) -> Self? { do { let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data) unarchiver.requiresSecureCoding = false let obj = unarchiver.decodeObject(of: self, forKey: NSKeyedArchiveRootObjectKey) if let error = unarchiver.error { print("Error:\(error)") } return obj } catch { print("Error:\(error)") } return nil } Everything works great until the data exceeds 87K (which, I understand, is the limit for exchanging data in GameCenter). The data is not sent and gives the following error: Async message[1FCA0D11-05DE-47D0-9714-983C8023F5C1] send error: FailedToSendData: , InternalError: reliable, maxPayloadSizeExceeded Interesting enough, I do not have this problem when using MCSession, as follows, even if data exceeds 87K: func sendData(dictionaryWithData dictionary: Dictionary<String, Any>, toPeer targetPeers: [MCPeerID]) { do { let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false) try session.send(dataToSend, toPeers: targetPeers, with: MCSessionSendDataMode.reliable) } catch { #if DEBUG print("CONNECTION MANAGER SEND DATA ERROR") #endif } } I have been doing research and found that I need to fragment data and send and receive it in packages. But I could not find a good explanation how to do it. Any help would be appreciated!
5
0
1k
Jul ’24
How to draw an arc in MKMapView?
Hello. I got another question.I need to draw half-circle on MKMapView knowing the center coordinates, start and end angles, and radius in nautical miles.I have subclassed MKOverlayPathRenderer:import UIKit import MapKit class IGAAcarsDrawArc: MKOverlayPathRenderer { let PI = 3.14159265 let radius : CGFloat = 10.0 var startAngle: CGFloat = 0 var endAngle: CGFloat = 3.14159 var latitude = 25.96728611 var longitude = -80.453019440000006 override func createPath() { let line = MKPolyline() let arcWidth: CGFloat = 5 let path = UIBezierPath(arcCenter: CGPointMake(CGFloat(latitude), CGFloat(longitude)), radius: self.radius, startAngle: startAngle, endAngle: endAngle, clockwise: true) path.lineWidth = arcWidth path.stroke() } }Now, it is not clear how do I use this to create MKPolyline and implement in mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay). Does anyone know how to draw an arc in MKMapView?Thanks a lot!
2
0
1.8k
May ’23
Remove only one polyline of several
Hello.I have two polylines on the map:var polylineRoute : MKGeodesicPolyline! var polylineFlight : MKGeodesicPolyline!I assign each of them a title and add them to the map like this (in different methods):let polyline = MKGeodesicPolyline(coordinates: &routeCoordinates, count: routeCoordinates.count) polyline.title = "route" self.mapView.addOverlay(polyline) self.polylineRoute = polylineandlet polyline = MKGeodesicPolyline(coordinates: &routeCoordinates, count: routeCoordinates.count) polyline.title = "flight" self.mapView.addOverlay(polyline) self.polylineFlight = polylineNow, when a specific action is triggered, I would like to remove the flight overlay and leave the route overlay intact.This does not work at all:func removeFlightPath() { self.mapView.removeOverlay(self.polylineFlight) self.polylineFlight = nil }The following works but removes both polylines:func removeFlightPath() { var overlays = mapView.overlays mapView.removeOverlays(overlays) }Is there a working way to remove only one polyline?Thanks a lot!
2
0
2.8k
Feb ’23
NSUserDefaults with tuples
Hello. I am using NSUserDefaults to save values, e.g.let defaultsLoad = NSUserDefaults.standardUserDefaults() // Strings string1 = defaultsLoad.stringForKey("String1") // Arrays let array1 = defaultsLoad.objectForKey("Array1") as? NSData if let array1 = array1 { self.array = NSKeyedUnarchiver.unarchiveObjectWithData(array1) as! [String] }My question is: how do I save and retrieve tuples in swift? I have a tuple variable(String,String,String)and an array of these tuples:[(String,String,String)]These do not work:let defaultsLoad = NSUserDefaults.standardUserDefaults() defaultsLoad.setObject(tuple1, forKey:"Tuple1") let tupleArrayData = NSKeyedArchiver.archivedDataWithRootObject(tupleArray) defaultsLoad.setObject(tupleArrayData, forKey: "TupleArray")let defaultsLoad = NSUserDefaults.standardUserDefaults() tuple1 = defaultsLoad.objectForKey("Tuple1") // This one does not show any error. The problem is with saving let tupleArrayData = defaultsLoad.objectForKey("TupleArray") as? NSData if let tupleArrayData = tupleArrayData { tupleArray = NSKeyedUnarchiver.unarchiveObjectWithData(tupleData) as! [(String,String,String)] }Thanks a lot!
6
0
4.2k
Aug ’22
Adding gradient background to SKScene
Hi.I am trying to add background with gradient color to my SKScene:class GameScene: SKScene { override func didMove(to view: SKView) { let gradientView = UIView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)) let image = UIImage.gradientBackgroundImage(bounds: CGRect(x: 0, y: 0, width: frame.width, height: frame.height), colors: [UIColor.yellow.cgColor, UIColor.blue.cgColor]) let background = SKSpriteNode(color: UIColor(patternImage: image), size: frame.size) addChild(background) } } extension UIImage { /** http://www.riptutorial.com/ios/example/14328/gradient-image-with-colors */ static func gradientBackgroundImage(bounds: CGRect, colors: [CGColor]) -> UIImage { let gradientLayer = CAGradientLayer() gradientLayer.frame = bounds gradientLayer.colors = colors UIGraphicsBeginImageContext(gradientLayer.bounds.size) gradientLayer.render(in: UIGraphicsGetCurrentContext()!) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image! } }This is not working. Is there a better way to add gradient background to the SKScene?Thanks a lot!EDIT:If I do this in didMove(to view:):self.view?.backgroundColor = UIColor.blue let backgroundDep = IGABackgroundLayer().gradientMetar() // My method to create CAGradientLayer backgroundDep.frame = self.view!.bounds self.view!.layer.insertSublayer(backgroundDep, at: 0)...background is created nicely but added SKNodes are not seen on top of it.
5
0
4.5k
Jul ’22
How to handle a disconnected player in a real-time match
Hi. Are there best practices in terms of how I should handle a disconnected player in a real-time match? In my app, once a player goes to background, he/she gets disconnected and the player is marked as temporarily unavailable on other players' devices. Is there any way that the disconnected player can return back to the same game when he/she becomes active again? It sounds a bit counterproductive to stop the whole match if one player has to disconnect quickly, for example to answer a call. Thank you!
1
0
900
Jul ’21
Fragment large size data sent and received using NSKeyedArchiver.archivedData in GameCenter
Trying to send and receive data in the GameCenter environment using the following methods: func sendData(dictionaryWithData dictionary: Dictionary<String, Any>,toPeer targetPeers: [GKPlayer]) { guard let match = self.match else { return } do { let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false) try match.send(dataToSend, to: targetPeers, dataMode: .reliable) } catch { #if DEBUG print("CONNECTION MANAGER SEND DATA ERROR") #endif } } public func match(_ theMatch: GKMatch,didReceive data: Data,forRecipient recipient: GKPlayer,fromRemotePlayer player: GKPlayer) { if match != theMatch { return } DispatchQueue.main.async { do { guard let message = NSDictionary.unsecureUnarchived(from: data) as? Dictionary<String, Any> else {return} ... <CODE> ... } ///Source: https://stackoverflow.com/questions/51487622/unarchive-array-with-nskeyedunarchiver-unarchivedobjectofclassfrom static func unsecureUnarchived(from data: Data) -> Self? { do { let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data) unarchiver.requiresSecureCoding = false let obj = unarchiver.decodeObject(of: self, forKey: NSKeyedArchiveRootObjectKey) if let error = unarchiver.error { print("Error:\(error)") } return obj } catch { print("Error:\(error)") } return nil } Everything works great until the data exceeds 87K (which, I understand, is the limit for exchanging data in GameCenter). The data is not sent and gives the following error: Async message[1FCA0D11-05DE-47D0-9714-983C8023F5C1] send error: FailedToSendData: , InternalError: reliable, maxPayloadSizeExceeded Interesting enough, I do not have this problem when using MCSession, as follows, even if data exceeds 87K: func sendData(dictionaryWithData dictionary: Dictionary<String, Any>, toPeer targetPeers: [MCPeerID]) { do { let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false) try session.send(dataToSend, toPeers: targetPeers, with: MCSessionSendDataMode.reliable) } catch { #if DEBUG print("CONNECTION MANAGER SEND DATA ERROR") #endif } } I have been doing research and found that I need to fragment data and send and receive it in packages. But I could not find a good explanation how to do it. Any help would be appreciated!
Replies
5
Boosts
0
Views
1k
Activity
Jul ’24
How to draw an arc in MKMapView?
Hello. I got another question.I need to draw half-circle on MKMapView knowing the center coordinates, start and end angles, and radius in nautical miles.I have subclassed MKOverlayPathRenderer:import UIKit import MapKit class IGAAcarsDrawArc: MKOverlayPathRenderer { let PI = 3.14159265 let radius : CGFloat = 10.0 var startAngle: CGFloat = 0 var endAngle: CGFloat = 3.14159 var latitude = 25.96728611 var longitude = -80.453019440000006 override func createPath() { let line = MKPolyline() let arcWidth: CGFloat = 5 let path = UIBezierPath(arcCenter: CGPointMake(CGFloat(latitude), CGFloat(longitude)), radius: self.radius, startAngle: startAngle, endAngle: endAngle, clockwise: true) path.lineWidth = arcWidth path.stroke() } }Now, it is not clear how do I use this to create MKPolyline and implement in mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay). Does anyone know how to draw an arc in MKMapView?Thanks a lot!
Replies
2
Boosts
0
Views
1.8k
Activity
May ’23
Remove only one polyline of several
Hello.I have two polylines on the map:var polylineRoute : MKGeodesicPolyline! var polylineFlight : MKGeodesicPolyline!I assign each of them a title and add them to the map like this (in different methods):let polyline = MKGeodesicPolyline(coordinates: &routeCoordinates, count: routeCoordinates.count) polyline.title = "route" self.mapView.addOverlay(polyline) self.polylineRoute = polylineandlet polyline = MKGeodesicPolyline(coordinates: &routeCoordinates, count: routeCoordinates.count) polyline.title = "flight" self.mapView.addOverlay(polyline) self.polylineFlight = polylineNow, when a specific action is triggered, I would like to remove the flight overlay and leave the route overlay intact.This does not work at all:func removeFlightPath() { self.mapView.removeOverlay(self.polylineFlight) self.polylineFlight = nil }The following works but removes both polylines:func removeFlightPath() { var overlays = mapView.overlays mapView.removeOverlays(overlays) }Is there a working way to remove only one polyline?Thanks a lot!
Replies
2
Boosts
0
Views
2.8k
Activity
Feb ’23
NSUserDefaults with tuples
Hello. I am using NSUserDefaults to save values, e.g.let defaultsLoad = NSUserDefaults.standardUserDefaults() // Strings string1 = defaultsLoad.stringForKey("String1") // Arrays let array1 = defaultsLoad.objectForKey("Array1") as? NSData if let array1 = array1 { self.array = NSKeyedUnarchiver.unarchiveObjectWithData(array1) as! [String] }My question is: how do I save and retrieve tuples in swift? I have a tuple variable(String,String,String)and an array of these tuples:[(String,String,String)]These do not work:let defaultsLoad = NSUserDefaults.standardUserDefaults() defaultsLoad.setObject(tuple1, forKey:"Tuple1") let tupleArrayData = NSKeyedArchiver.archivedDataWithRootObject(tupleArray) defaultsLoad.setObject(tupleArrayData, forKey: "TupleArray")let defaultsLoad = NSUserDefaults.standardUserDefaults() tuple1 = defaultsLoad.objectForKey("Tuple1") // This one does not show any error. The problem is with saving let tupleArrayData = defaultsLoad.objectForKey("TupleArray") as? NSData if let tupleArrayData = tupleArrayData { tupleArray = NSKeyedUnarchiver.unarchiveObjectWithData(tupleData) as! [(String,String,String)] }Thanks a lot!
Replies
6
Boosts
0
Views
4.2k
Activity
Aug ’22
Adding gradient background to SKScene
Hi.I am trying to add background with gradient color to my SKScene:class GameScene: SKScene { override func didMove(to view: SKView) { let gradientView = UIView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)) let image = UIImage.gradientBackgroundImage(bounds: CGRect(x: 0, y: 0, width: frame.width, height: frame.height), colors: [UIColor.yellow.cgColor, UIColor.blue.cgColor]) let background = SKSpriteNode(color: UIColor(patternImage: image), size: frame.size) addChild(background) } } extension UIImage { /** http://www.riptutorial.com/ios/example/14328/gradient-image-with-colors */ static func gradientBackgroundImage(bounds: CGRect, colors: [CGColor]) -> UIImage { let gradientLayer = CAGradientLayer() gradientLayer.frame = bounds gradientLayer.colors = colors UIGraphicsBeginImageContext(gradientLayer.bounds.size) gradientLayer.render(in: UIGraphicsGetCurrentContext()!) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image! } }This is not working. Is there a better way to add gradient background to the SKScene?Thanks a lot!EDIT:If I do this in didMove(to view:):self.view?.backgroundColor = UIColor.blue let backgroundDep = IGABackgroundLayer().gradientMetar() // My method to create CAGradientLayer backgroundDep.frame = self.view!.bounds self.view!.layer.insertSublayer(backgroundDep, at: 0)...background is created nicely but added SKNodes are not seen on top of it.
Replies
5
Boosts
0
Views
4.5k
Activity
Jul ’22
How to handle a disconnected player in a real-time match
Hi. Are there best practices in terms of how I should handle a disconnected player in a real-time match? In my app, once a player goes to background, he/she gets disconnected and the player is marked as temporarily unavailable on other players' devices. Is there any way that the disconnected player can return back to the same game when he/she becomes active again? It sounds a bit counterproductive to stop the whole match if one player has to disconnect quickly, for example to answer a call. Thank you!
Replies
1
Boosts
0
Views
900
Activity
Jul ’21