Skobbler background mode without SKTNavigationManager - ios

I'm developing an IOS app in swift language with the Skobbler navigation SDK.
I try to allow the user to use navigation while in background mode (IPhone locked).
I have question stated below :
1) Is it possible to do so without using the SDKTools and the SKTNavigationManager ? We only use SKMaps.frameworks functions.
With this configuration, I can't use the allowBackgroundNavigation
property of SKTNavigationConfiguration like in the demo.
I set
SKPositionerService.sharedInstance().worksInBackground = true
and allowed the "location Update in BackgroundMode" to the info.plist. Unfortunately the updateCurrentLocation doesn't triggered in background and navigation doesn't works neither.
Thank you very much in advance :-) !!
P.S. : I succeeded to run a short code in background with the official library CCLocationManager. So my app seems correctly configured...

The hotfix for this issue can be downloaded from here:
ObjC: https://www.dropbox.com/s/ruk6at2fju0rdd7/SKMaps_2_5_1.zip?dl=0
Swift: https://www.dropbox.com/s/lgbdherhqzudy2a/SKMapsSwift_2_5_1.zip?dl=0

Sorry..this is not an answer, but a "Same Problem". updatedCurrentLocation is not called when the app is in the background.
Thought I add some more code to give more info and perhaps find the cause:
My code:
SKPositionerService.sharedInstance().delegate = self
SKPositionerService.sharedInstance().worksInBackground = true
SKPositionerService.sharedInstance().automaticLocationUpdatePause = false
SKPositionerService.sharedInstance().startLocationUpdate()
Also tried putting SKPositionerService.sharedInstance().startLocationUpdate() as first line. No luck.
When I run a CLLocationManager alongside the SKPositionerService like so:
locManager = CLLocationManager()
locManager.desiredAccuracy = 10000
locManager.distanceFilter = 10000
locManager.allowsBackgroundLocationUpdates = true
locManager.pausesLocationUpdatesAutomatically = false
locManager.startUpdatingLocation()
updatedCurrentLocation IS being called while in background.
I used this when I was running 2.5.0 as that version was not yet iOS9 ready, but I thought that 2.5.1 would be. This of course is a horrible workaround as a 2nd locationmanager eats battery.
Could it be that, in the SKPositionerService implementation, you are not setting CLLocationManager().allowsBackgroundLocationUpdates to true when SKPositionerService.sharedInstance().worksInBackground is set to true?
btw I'm running the 2.5.1 hot fix posted here.
btw2: This can not be tested in the simulator. The simulator will call updatedCurrentLocation even when the app is 'backgrounded'. I'm guessing because the simulator doesn't really have a 'background' mode.
btw3: I would be very surprised if background mode works for the SDKTools Navigation Manager... with this 2.5.1. hot fix)

Related

Mixpanel integrated in iOS SDK is not sending events

​I have an iOS SDK project with lots of modules (in Objective-C).
I want to start tracking events to see how my clients use our SDK but I can't see anything in the insights tab. What am I doing wrong?
 
In the point of entry to the SDK I have added this (just following the docs):
[Mixpanel sharedInstanceWithToken:#"myTOKEN"];
self.mixpanel.serverURL = #"https://api-eu.mixpanel.com";
[self.mixpanel track:#"Video play" properties:#{
#"genre": #"hip-hop",
#"duration in seconds": #42,
}];
I can see with breakpoints that the code it’s executed, however my insights are completely empty.
I also tried adding events with the codeless tracking, and while it looks like it’s working and I can connect to the app, the events aren’t appearing in the insights tab.
 
​
I think you need to assign the shared instance to your local property if that hasn't been done outside of the code you've posted.
[Mixpanel sharedInstanceWithToken:#"myTOKEN"];
self.mixpanel = [Mixpanel sharedInstance]; // assign here
self.mixpanel.serverURL = #"https://api-eu.mixpanel.com";
[self.mixpanel track:#"Video play" properties:#{
#"genre": #"hip-hop",
#"duration in seconds": #42,
}];

UIAccessibilityElement `accessibilityCustomActions` not working properly

I have created an instance of UIAccessibilityElement in order to provide a set of custom actions together with some additional information (i.e. accessibilityLabel + accessibilityHint)
The problem is that VoiceOver doesn't announce the existence of custom actions. They are there, they work, but don't get announced. Also, custom actions' hint is not being announced as well.
Any ideas?
Code to generate the element is below:
private lazy var accessibilityOverviewElement: UIAccessibilityElement = {
let element = UIAccessibilityElement(accessibilityContainer: self)
element.accessibilityLabel = viewModel.accessibilityOverviewTitle
element.accessibilityHint = viewModel.accessibilityOverviewHint
element.isAccessibilityElement = true
let close = UIAccessibilityCustomAction(
name: viewModel.accessibilityCloseActionTitle,
target: self,
selector: #selector(self.accessibilityDidClose))
close.accessibilityHint = viewModel.accessibilityCloseActionHint
let expand = UIAccessibilityCustomAction(
name: viewModel.accessibilityExpandActionTitle,
target: self,
selector: #selector(self.accessibilityDidExpand))
expand.accessibilityHint = viewModel.accessibilityExpandActionHint
element.accessibilityCustomActions = [close, expand]
return element
}()
I compute the element's frame in viewDidLayoutSubviews()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var frame = view.bounds
frame.size.height = SleepAidMinifiedPlayerViewController.defaultHeight
accessibilityOverviewElement.accessibilityFrameInContainerSpace = frame
}
Finally, I need to be able to enable/disable accessibility since this view controller slides from the bottom and hides, but it's not completely removed from the view hierarchy (so VoiceOver still focuses on its elements)
func setAccessibility(enabled isEnabled: Bool) {
view.accessibilityElements = isEnabled ? [accessibilityOverviewElement, /* + other accessible elements*/].compactMap { $0 } : []
}
Thanks!
Any ideas?
I already created a radar about this problem: VoiceOver doesn't read out the custom actions anymore - Nov 4, 2019 at 5:01 PM – FB7426771.
Description: "Natively, in iOS 13, VoiceOver doesn't announce available actions even if they're present: example in the alarms settings, select an alarm and no actions is read out (it's OK in iOS 12) while they exist.
Moreover, if I create an element in an app with custom actions, they won't be announced in iOS 13 but they can be used if I know they're here (up and down swipe to get them).
However, if i use an older app targeting iOS 12, my elements containing custom actions are perfectly spelled out with the "actions available" announced with an iOS 12 device while the iOS 13 device does announce them 'sometimes'.
Please correct this huge turning back in the next iOS 13.3 version because it's extremely penalizing for the VoiceOver users."
No answers since but it's important to deliver a solution in a future version: I'm looking forward to seeing this correction in the next release notes.
However, your implementation should make your app work as desired, that's not the problem in my view ⇒ there are many useful examples (code + illustrations) if you need further explanations about some VoiceOver implementations.
Make your app run under iOS 12 and notice that it works while it's not the case under iOS 13.😰
⚠️ ⬛️◼️🔳▪️ EDIT ▪️🔳◼️⬛️ ⚠️ (2020/03/17)
The problem is that VoiceOver doesn't announce the existence of custom actions. They are there, they work, but don't get announced. Also, custom actions' hint is not being announced as well.
Even if you didn't mention your iOS version you're working with, I think this is iOS 13 because this weird behavior has been introduced making itself scarce in this version: no WWDC videos or info on the Apple website. 😤
This dedicated a11y site mentioned this modification ⟹ "iOS 13 introduced a new custom actions behavior: the "actions available" announcement isn't always present anymore.
It was previously offered to every element containing custom actions but, now, it will occur when you navigate to another element that contains a different set of actions.
The purpose is to prevent repetitive announcements on elements where the same actions are present as the previous element." 🤓
Take a look at this SO answer that highlights a response from a Technical Support Incident about this subject. 😉
Conclusion: if you need to use the announcement of the custom actions on each element they're implemented, use iOS 12 otherwise you'll have to work with this new behavior that wasn't explained anywhere and is definitely not efficient for the VoiceOver users ⟹ the Apple Technical Support claims that's the way it works from now.😰
⚠️ ⬛️◼️🔳▪️ EDIT ▪️🔳◼️⬛️ ⚠️ (2022/11/15)
I haven't this problem anymore, even in iOS 15. 🥳
If you're still in the same still bad situation in iOS 16, I suggest to check you've ticked the box Accessibility-VoiceOver-Verbosity-Actions-Speak in your device settings to make it work as expected (⟹ source). 👍
However, I've had no news from Apple regarding my TSI. 😵‍💫

iOS 11.4 not asking Privacy Usage ( Privacy - Motion Usage Description has been set )

I'm stumped, iOS 11.4 ( 15F79 ), iPhone 6. Cannot get the App to Ask for Motion Data. info.plist has been set via the editor and double checked via the info.plist open in textWrangler, Also deleted key and saved via textWrangler.
<key>NSMotionUsageDescription</key>
<string>This app needs your Phones motion manager to update when the phone is tilted. Please allow this App to use your phones tilt devices</string>
I have deleted then reinstalled the app about 10 times. I have restared the phone 5 times. I have checked through settings and my app does NOT show up in Privacy-Motion and Fitness or anywhere else in settings. I am using a free developer account, maybe that has something to do with it?
I created a new Xcode game template and changed nothing apart from importing CoreMotion and this code
**** Edited, sorry I forgot to say I had started the instance, just forgot to put it here, just in case someone thinks that's the problem ************
let motionManager = CMMotionManager()
override func didMove(to view: SKView) {
motionManager.startDeviceMotionUpdates()
if motionManager.isDeviceMotionActive == true {
motionManager.accelerometerUpdateInterval = 0.2
motionManager.startAccelerometerUpdates(to: OperationQueue.current!, withHandler: {
(accelerometerData: CMAccelerometerData!, error: NSError!) in
let acceleration = accelerometerData.acceleration
print(accelerometerData)
} as! CMAccelerometerHandler)
}else{
print(CMMotionActivityManager.authorizationStatus().rawValue)
}
which prints a 0 ( an Enum - case not determined ) to the console.
In my actual app it was a 3 ( same Enum - case Denied ).
As I've said, I have uninstalled, reinstalled, edited plist via Xcode and text wrangler ( a code editor ) , tried different versions of the code above, tried the code in different places ( in did move to view, in class )tried code off apple docs. etc.... I haven't been asked the NSUsage question and the App keeps crashing.
I have looked for ways to get the Alert fired up, As in CLLocationManager.requestWhenInUseAuthorization() but I cannot find a comparable CMMotion version ( I don't think there is one. ) I have created a new swift file , imported Foundation and CMMotion and just put that code there, But still no Alert asking for Motion Data.
I tried a single view app template instead of a game template thinking that might be the issue, Nope.
What do I do?
Any help Appreciated. Thanks
You are confusing two related but different classes.
CMMotionManager gives access to accelerometer, magnetometer and gyroscope data. It does not require any user permission as this information is not considered privacy related.
In your else clause you are checking the authorisation status of CMMotionActivityManager. This object reports the device motion type (walking, running, driving). This information is considered privacy related and when you create an instance of this class and request data from it, the permissions alert is displayed.
The reason your else is being triggered is because you are checking isDeviceMotionActive; this will be false until you call startDeviceMotionUpdates, which you never do. Even if you used isAccelerometerActive you would have a problem because you call startAccelerometerUpdates in the if clause which will never be reached.
You probably meant to check isAccelerometerAvailable. If this returns false then there isn't much you can do; the device doesn't have an accelerometer.
Update
It doesn't make sense to check isDeviceMotionActive immediately after calling startDeviceMotion:
You know it's active; you just started it
I imagine the start up takes some time, so you could expect to get false if you check immediately.
Apple recommends that you do not have more than one observer in place for each motion device type, so the purpose of check the is...Active to ensure you don't call start... again if you have already done so.
If you only want gyroscope data then you don't need to call startDeviceMotionUpdates at all.

.or query in parse unity crashes on iOS

I'm doing a .or query which in every platform works fine except in iOS.
As soon it reaches the line where it does the .or, it crashes with:
System.Collections.Generic.List> doesn't implement interface System.Collections.Generic.IEnumerable>
Assertion: should not be reached at mini-trampolines.c:183
Here's the code:
var isChallenger = ParseObject.GetQuery("Match")
.WhereEqualTo("Challenger",fb.loggedUser);
var isChallenged = ParseObject.GetQuery("Match")
.WhereEqualTo("Challenged",fb.loggedUser);
ParseQuery<ParseObject> query = isChallenger.Or (isChallenged); // Crashes here.
I'm doing it just like in the docs, not sure what's wrong.
Any help would be much appreciated!
Thanks,
Pablo
I think this is a bug I reported here: https://developers.facebook.com/bugs/750897958275392/
Except, I only saw this bug when using ParseQuery. The workaround I used is to use ParseQuery only, but I see you're already doing that. Is the code you posted exactly the same as the code you're actually using?

App used to work with AIR 3.2, doesn't work with AIR 3.5

I'm getting this error when I press a button in a flash/air app that used to work in the AIR 3.2 SDK - now upgraded to the AIR 3.5 SDK. Any help much appreciated.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at seed_template_fla::MainTimeline/frame7()[seed_template_fla.MainTimeline::frame7:31]
at flash.display::MovieClip/gotoAndPlay()
at seed_template_fla::MainTimeline/gotoPage() [seed_template_fla.MainTimeline::frame1:20]
at seed_template_fla::MainTimeline/gotoRepro() [seed_template_fla.MainTimeline::frame1:12]
I'm creating an app for iPhone using Flash CS6 on Mac and exporting using the Air 3.5 SDK. I also have the AIR 3.5 runtime installed.
The app is very simple at the moment. It basically moves from frame to frame when you press a button using the gotoAndPlay(frameNr) function. There are some hexes on the frames that update an array of numbers when clicked. They are also toggled visible/not visible.
This used to work perfectly using the AIR 3.2 SDK, but I recently downloaded the AIR 3.5 SDK from adobe and added it through flash (Help>Manage Air SDK) and set it as the build target in File>Publish Settings>Target.
When I switch back to AIR 3.2 SDK, the app works perfectly again.
Also, when I upload the app to my iPhone 4S running IOS 5.1 using AIR 3.5 SDK, I just see a black screen with 5 loading dots flashing. This also works fine with AIR 3.2 SDK.
This is the code for frame 7
The last line is line 31.
stop();
techtitle.text = "Select Trait";
techdesc.text = "Spend points to change core stats and other special abilities";
points.visible = false;
techpoints.visible=false;
pointsbalance.text = myPoints.toString();
btn_tech.visible = false;
curTechSelected = null;
trace("set hexes invisible");
for (var j:int = 0; j <= 67; j++) {
if (hexStatusb[j] == 1) {
this["btn_hex_"+j+"b"].visible = false;
}
}
function onBtnHex37bClick(event:MouseEvent):void
{
techtitle.text = "tech1";
techdesc.text = "tech1 description"
techpoints.text = "-2";
points.visible = true;
techpoints.visible=true;
btn_tech.visible = true;
curTechSelected = btn_hex_37b;
curTechSelectedNr = 37;
curTechPoints = 2;
}
trace(this["btn_hex_37b"]);
btn_hex_37b.addEventListener(MouseEvent.CLICK, onBtnHex37bClick);
OK - so, after trying out lots of things, I figured out why this is happening.
Solution: get rid of all TFL text objects when running AIR 3.5 SDK
It seems that the TFL Text library wasn't being loaded properly at runtime. Something crucial that I neglected to mention was that I was getting this warning message (similar here http://forums.adobe.com/thread/825637)
Content will not stream... The runtime shared libraries being preloaded are textLayout_1.0.0.05... TFLText
and this warning message in the output
Warning: Ignoring 'secure' attribute in policy file from http://fpdownload.adobe.com/pub/swz/crossdomain.xml. The 'secure' attribute is only permitted in HTTPS and socket policy files.
Simply removing all TFLText objects and changing them to classic text makes the app work fine again.
#csomakk Great news. I have found the answer. You can publish in 3.5 and 3.6 and have your TLF Text too. I posted a write-up on my blog that shows exactly how to do it.
To get started: the error message states that something is null.. it means, that the program doesn't know, where to look for it. It can happen, when you didn't create the object (btn_hex_37b = new MovieClip()); or you haven't even created a variable for it.
on the given line (btn_hex_37b.addEventListener(MouseEvent.CLICK, onBtnHex37bClick);) only btn_hex_37b can be null, because onBtnHex37bClick exists, and if it wouldn't, the program wouldn't compile.
The reason it came up when switching to AIR 3.5 is probably that it calls some creation functions in different order. Go to the line where you define the btn_hex_37b variable. Search for that functions calling.. Make sure, that btn_hex_37b is created before going to frame7.
Also, if its not a vital, to have onBtn_hex_37bClick, you can do the following:
if(btn_hex_37b){
btn_hex_37b.addEventListener(MouseEvent.CLICK, onBtnHex37bClick);
}
the if will check if btn_hex_37b is not null.
On the else method, you can give a timeouted method(but that is ugly), or give the eventlistener right after the creation of the object.
Hope this helped.
For Flash CS6, copy this swc:
/Applications/Adobe Flash CS6/Common/Configuration/ActionScript 3.0/libs/flash.swc
Into my Flash Builder project using these steps:
http://interactivesection.files.wordpress.com/2009/06/include_fl_packages_in_flex_builder-1.jpg
and then use this link
http://curtismorley.com/2013/03/05/app-used-to-work-with-air-3-2-or-3-4-doesnt-work-with-air-3-5-or-3-6/#comment-241102

Resources