How is Cycloramic possible on iOS? - ios

I just came across cycloramic app, which rotates the iPhone automatically to take 360 panoramas (you place the phone upright on a flat surface and it does its magic). I am blown away.
And my question is, how is it possible to control the vibration motor in iOS programmatically? I know you can vibrate it with AudioServices. Is it just straightforward vibration, but interrupted so it has shorter duration? Or is there something in the SDK I'm missing?
And if the app is using internals, how did it make it to App Store?
Any comments welcome

I've been struggling with this last week too. I downloaded Cycloramic and can't imagine how they achieve that effect. In fact, the phone starts with a short vibration and then it continues with a lengthy vibration that makes the phone rotate completely.
The default vibration in the iOS API is:
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
and lasts 4 milliseconds with one millisecond of silence. You can try to chain the same function call several times but there will be always an interruption between two calls. I think there is no way to make a lengthy vibration that lasts more than 4 milliseconds :(

Related

Is There A Software Way to "Wake" a "Sleeping" Touchscreen on an iPhone?

Here's my issue. It may be device-specific, but I won't know for a bit. I haven't heard about it from my beta-testers, but I don't actually hear much from them anyway. There's a good chance they wouldn't report it, as it's such a minor "niggle."
I have an iPhone SE as my LET (Low-End Target). I have an app that keeps it awake for hours (a clock that runs while powered).
After a number of hours, the app triggers an alarm.
You dismiss the alarm by touching the screen. The alarm makes a transparent UIView with a touch gesture recognizer attached, visible.
I have found that, after several hours, you need to touch the screen TWICE. I suspect that it's because the OS puts the touch sensor into some kind of "sleep" mode, after a long time with no input.
I can't get this to happen without waiting for many hours.
I haven't seen this documented anywhere, so I'm wondering if there's some kind of UIDevice call that I can make to "prod" the touchscreen awake when the alarm sounds, so the first touch works.
Any ideas.
Call this app become active in appDelegate UIApplication.shared.isIdleTimerDisabled = true

How would one take a picture at programmed interval -iOS/iPhone

Seems like this is an often enough asked question. Rather than asking if possible, I'm wondering if there's any potential workarounds.
I understand iPhone background tasks will not allow one to take pictures from a Background Task.
Would there be any other solution to capturing a picture programatically, (1 hr+ intervals) on iOS?
It appears there a variety of potential solutions on Android:
Background services (execute camera function from background)
A wakelock (keeps the App alive at the expense of battery)
Timer (utilize timer to start a service or app)
What would be a potential solution on iOS, or is there actually NO solution for this. Not being an iPhone user myself, are there not any time lapse apps that have the screen turn off??

Show advertisement at regular interval of time when iPhone is running

I am working on the app that shows Ads (Video or image) when iPhone is running. If I open any app(eg. Twitter) then also my Ads should be visible at particular interval of time. Is it possible to do so?
No. Your app will not be informed about any other apps being launched. Even if it were, you can't "force-grab" the foreground to display videos. That would totally violate any user interface principle established by iOS.
Besides the technical aspect I'd have my doubts of such an app surviving app review in general, though I don't know the specific part of the TOS right now.
It is possible to show your ads inside your application in intervals or in any pattern you like. However it is not possible to bring your app to foreground when in background to play ads, it is actually not recommended at all. Best thing you can do is set a timer when the app gets in background to send a notification.

Shake functionality in a music application

I have developed a small music app by using AVPlayer and MPMediaPickerControlLibrary with all the normal required functionalities for a music app. The app is also capable of running in the background when the screen is locked.
Now, what I want is to start the app when the screen is locked through a shake and soon as the app starts the current song should start playing.
I am not able to achieve this from a long time
Any suggestions on this will be highly appreciated or any other workaround apart from shake to turn on the music in the app when the screen is locked in iPhone.
Thanks in advance.
You need to implement the a CMMotionManager object, but keeping it running all the time in background will be a major power consumption issue.
Modifying the updateInterval property to reduce the number of updates will defeat the purpose, given that you may miss a shake in background.
Now, if the app was terminated by the user, then no motionManager object will be available until the user launches the app again.

touchesMoved called at irregular intervals

I'm making a game for iOS where you mostly drag big objects across the screen. When I run the game on an actual iPad/iPhone for a while (continuously dragging the object in circles across the screen) every 5 minutes or so the dragged object goes all stuttery for about 10-30 seconds. Then, it goes back to moving silky-smooth.
Visually, it looks like the game's frame rate dropped to 15 fps for a while, but in actual fact it's running at rock-solid 60 fps all the time. However, I noticed that the only thing that doesn't move smoothly is the dragged object, while the rest of the game is all running perfectly smooth.
This led me to believe that the stuttering is related to the touch input in iOS. So I started looking at touchesMoved, and saw that it's normally called every 16 milliseconds (so touch input runs at 60 fps). So far so good.
Then I noticed that when the object starts stuttering, touchesMoved starts being called at weird time intervals, fluctuating wildly between 8 milliseconds and 50 milliseconds.
So while the touchscreen is in this weird state, sometimes touchesMoved will get called just 8 milliseconds after the previous call, and sometimes it won't get called until 50 ms after the previous call. Of course, this makes the dragged object look all choppy because its position is updated at irregular intervals.
Do you have any idea what could be causing touchesMoved to stop being called at regular intervals, as it normally does?
Bonus:
-Whenever I tilt the screen to force the screen orientation to change, roughly 70% of the time the touchscreen goes into the aforementioned state where touchesMoved starts being called irregularly. Then after 10-20 seconds it goes back to normal and everything looks smooth again.
-I've tried this on two iPads and two iPhones, with iOS 6 and 7, and the issue appears in all of these devices.
-An OpenGLES view is used to display the graphics. It syncs to the display refresh rate using CADisplayLink.
-The Xcode project I'm using to test this has been generated by the unity3d game development tool, but I've found several non-unity games where the same issue appears. this appears to be a system-wide problem. note I'm measuring the timings in objective-c using CFAbsoluteTimeGetCurrent, completely outside unity.
This is not a bug in Unity.
Something inside the OS is getting into a bad state and the touch-drag messages stop flowing smoothly. Sometimes you'll get multiple updates in a frame and sometimes you'll get none.
The issue does not happen on iPhone4 or below, or if the game is running at 30Hz frame rate.
I experienced this bug while using an in-house engine I'd written while working at a previous company. It first manifest itself after upgrading the UI system of a scrabble genre game, where you drag the tiles about on the screen. This was utterly bizarre, and I was never able to pin down the exact reproduction steps, but they seem to be timing related, somehow.
It can also be seen on Angry Birds (unless they've fixed it by now), and a variety of other games on the market, basically anything with touch-drag scrolling or movement. For Angry Birds, just go into a level and start scrolling sideways. Most of the time it'll be silky smooth, but maybe 1 in 10 times, it'll be clunky. Re-start the app and try again.
A workaround is to drop the input update frequency to 30Hz for a few frames. This jolts the internals of the OS somehow and gives it time to straighten itself out, so when you crank it back up to 60Hz, it runs smoothly again.
Do that whenever you detect that the bad state has been entered.
I've also run into this. I can verify that it's a bug in Unity 4.3.x.
My 4.2.x builds process touches on device at 60Hz with TouchPhase.Moved on every frame.
My 4.3.x builds get 20-40Hz with TouchPhase.Stationary being emitted on dropped frames.
TestFlight history saved my sanity here.
Don't forget to file a bug with UT.
It's a real disaster. Sometimes it's lag and sometimes it's really smooth. It lags even when GPU and CPU utilization are below 10%. it's not Unity bug. I'm using cocos2d v3.
If someone found a cure, please post it!
I've been running into this as well. My current hypothesis which I still have to verify is that if you ask for a given frame rate (eg. 60fps), but your actually achieved frame rate is less than that (eg. 45fps) that this causes a timing/race condition issue between Unity requesting inputs from iOS at a higher frame rate than it actually is running at. However, if you set it to 30fps (at least in my UNity 5.2 tests with iOS 9.1) then you get a solid 30Hz of input. When I disabled a chunk of my game and it was running at a very solid 60fps, then I would consistently get 60Hz of input from the touch screen. This is what I have for now, but I have to prove this in a simple project which I haven't had time to do yet. Hope this helps someone else.
I found a potential solution to this problem here: https://forums.developer.apple.com/thread/62315 (posting here because it took me a lot of research to stumble across that link whereas this StackOverflow question was the first Google result).
To follow up on this, I got a resonse on my bug report to Apple. This
is the response:
"As long as you don't cause any display updates the screen stays in
low power and therefore 30hz mode, which in turn also keeps the event
input stream down at 30 hz. A workaround is to actually cause a
display update on each received move, even if it is just a one pixel
move of a view if input is needed while no explicit screen update will
be triggered."
In my application, using a GLKView, I set its
preferredFramesPerSecond to 60. Occasionally, my input rate would
randomly drop to 30hz. The response from Apple doesn't fully explain
why this would happen, but apparently the expected method of handling
this is to call display() directly from touchesMoved() while dragging.
I've subclassed GLKView and I set preferredFramesPerSecond to 60. On
touchesBegan(), I set isPaused=true, and start calling display()
within touchesMoved(). On touchesEnd(), I set isPaused=false. Doing
this, I'm no longer having any issues - the app is more performant
than it's ever been.
Apple's example TouchCanvas.xcodeproj does all drawing from within
touchesMoved() as well, so I guess this is the intended way to handle
this.
As far as I can tell, your best bet to achieve a smooth look may be to interpolate between touch events, rather than immediately mapping your objects to your touch position.
tl;dr: It seems just having a CADisplayLink causing any OpenGL context or Metal device to draw at 60fps can cause this.
I was repro'ing this on my iPhone 7 Plus w/ iOS 10.2.1.
I made a small sample simple app with a CADisplayLink with preferredFramesPerSecond = 60, and tried the following rendering approaches:
GLKView w/ display()
CAEAGLLayer, used as prescribed by Apple at WWDC (opaque, sole layer, fullscreen, nothing drawn above it)
MTLDevice
In each case, the render method would only clear the screen, not try drawing anything else.
In each case, I saw the input rate problem.
The following "tricks" also seemed to do nothing, when called inside touchesMoved:
Calling glkView.setNeedsDisplay() (with enableSetNeedsDisplay set to true)
Moving some other view
Calling glkView.display() (actually, seems like it can raise your input rate to 40 events per second. But it doesn't look any better, as far as I can tell, and seems wrong to do, so I wouldn't recommend it.)
I gave up, after running all these tests. Instead, I interpolate my object between the touch positions instead. So it's what I'd recommend, too.
But I figured I'd include my research here in case somebody else takes a stab at it and finds a better solution.

Resources