How to Automatically OpenURL on NSTimer in Swift - ios

I'm using the following code to open a URL with a UIButton in Swift
UIApplication.sharedApplication().openURL(url!)
This works very well on its own, but I'm looking for away to do this with an NSTimer with the goal being that the URL opens without any "buttons pressed" by the user.
Can anyone provide assistance?

Try like this in swift language
NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "timerFunctionRun", userInfo: nil, repeats: false)
and function Like ths
func timerFunctionRun () {
UIApplication.sharedApplication().openURL(url!)
}
its work fine ...

In Swift use:
dispatch_after(2.0, dispatch_get_main_queue(), {
// call your button action here
})
You don't really need a timer in your case unless you're repeating the opening of this URL.

Related

Get device volume - issue

Coincidentally, I encountered some strange behavior from my source code while developing an app:
I have started an interval that calls a function to output the set volume of the device.
When testing the code on a real device (iPhone X), I noticed that the "value of the volume does not seem to change" when I press one of the volume buttons.
This was the code I was using:
Timer.scheduledTimer(
timeInterval: 0.5,
target: self,
selector: #selector(self.getSystemVolume),
userInfo: nil,
repeats: true)
#objc func getSystemVolume() {
let outputVolume = AVAudioSession.sharedInstance().outputVolume
print(outputVolume)
}
Note: I'm not sure if this is a bug or not - could be!
However: Does anyone now how to fix behavior? Any help would be very appreciated :)
Looks like I've found a working solution on my own:
I've added those lines:
let volumeView = MPVolumeView()
volumeView.setNeedsLayout()
I got no idea why these lines cause the code to work, but however - now it's working.
#objc func getSystemVolume() {
let volumeView = MPVolumeView()
volumeView.setNeedsLayout()
let outputVolume = AVAudioSession.sharedInstance().outputVolume
print(outputVolume)
}
I really hope somebody could add a comment why these lines fix the code. :)

Swift 3 - performSegue when animation sequence stop

I need help because i can't find example to do exactly what I want need anywhere.
I want to animate a simple png sequence, then call a performSegue once it's completed (that's my main problem)
So I tried with
InitImage.animationImages = [
UIImage(named:"load1.png")!,
UIImage(named:"load2.png")!,
UIImage(named:"load3.png")!,
/* 20 more images... */
]
InitImage.animationDuration = 2.5
InitImage.animationRepeattCount = 1
InitImate.startAnimating()
so it animates but call the segue too soon. I found that i should probably use
UIView.animate(withDuration : ...)
But I can't find an example written in Swift3 that animates a sequence of files.
Could someone show me the way?
thanks.
The simplest way I think is to make a timer
Timer.scheduledTimer(timeInterval: InitImage.animationDuration * Double(InitImage.animationImages?.count ?? 0), target: self, selector: #selector(push), userInfo: nil, repeats: false)
and selector
func push() {
.... perform segue
}
The simplest option is to use performSelector with afterDelay, since the self is an #objc UIViewController:
self.perform(#selector(segueToDetailViewController), with: self, afterDelay: InitImage.animationDuration)
And selector:
func segueToDetailViewController() {
self.performSegue( ... etc ... )
}
The code above is not multiplying the animation duration by the number of images because when I ran the code, I found that the animation duration for all images was 2.5 seconds.

How to repeat every X seconds in Swift?

I am trying to build a simple single view app which runs an infinite slide show of a selection of images with a time delay between each image change.
The code I wrote for this is below. I tried to put this into viewDidLoad and viewDidAppear but the screen remained blank which I guess is because the function never finishes due to the infinite loop.
I learnt a bit of Python before iOS and with tkinter, your code would go into the mainloop. But I am not quite sure how to do the equivalent in Swift
Could someone please explain why I am having this problem and how to do this in Swift. Thanks.
var arrayimages: [UIImage] = [UIImage(named: "charizard")!,UIImage(named:"Flying_Iron_Man")!]
var x: Int = 0
var images: UIImage
let arraycount = arrayimages.count
repeat{
images = arrayimages[(x % arraycount)]
sleep(1)
slideshow.image = images
x++
} while true
NB: slideshow is an image view outlet.
You're looking for NSTimer
let timer = NSTimer.scheduledTimerWithTimeInterval(
1.0, target: self, selector: Selector("doYourTask"),
userInfo: nil, repeats: true)
The first argument is how frequently you want the timer to fire, the second is what object is going to have the selector that gets called, the third is the selector name, the fourth is any extra information you want to pass as a parameter on the timer object, and the fifth is whether this should repeat.
If you want to stop the code at any future point:
timer.invalidate()
Create a repeating NSTimer:
var timer = NSTimer.scheduledTimerWithTimeInterval(2.0,
target: self,
selector: "animateFunction:",
userInfo: nil,
repeats: true)
Then write a function animateFunction:
func animateFunction(timer: NSTimer)
{
//Display the next image in your array, or loop back to the beginning
}
Edit: Updated for modern Swift versions: (>= Swift 5)
This has changed a lot since I posted this answer. NSTimer is now called Timer in Swift, and the syntax of the scheduledTimer() method has changed. The method signature is now scheduledTimer(timeInterval:target:selector:userInfo:repeats:)
Also, the way you create a selector has changed
So the call would be
var timer = Timer.scheduledTimer(timeInterval: 2.0,
target: self,
selector: #selector(animateFunction(_:)),
userInfo: nil,
repeats: true)
And the animateFunction might look like this:
func animateFunction(timer: Timer)
{
//Display the next image in your array, or loop back to the beginning
}

Swift - NSTimer passing wrong value for userInfo param

I recently took it upon myself to learn the Swift programming language and I love it. To help me learn, I have been working on a couple of simple apps using XCode 7. One of those apps is a flashlight and one of the features is a strobe light. I decided on using the NSTimer class to schedule the flashlight toggle functionality to be called at a set time interval, thus giving a nice strobe effect. My first crack at the timer code is as follows :-
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "toggleTorch:", userInfo: false, repeats: true)
As you can see here, I am using my own custom made Torch object to handle the flash toggle functionality. I pass the torch object I have specified as an instance variable as the target param and then I call the following function in the Torch class, which I pass as selector :-
func toggleTorch(adjustingBrightness: Bool) -> Bool {
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
defer {
device.unlockForConfiguration()
}
guard device.hasTorch else {
return false
}
do {
try device.lockForConfiguration()
if !adjustingBrightness && device.torchMode == AVCaptureTorchMode.On {
device.torchMode = AVCaptureTorchMode.Off
}
else if !adjustingBrightness && device.torchMode == AVCaptureTorchMode.Off {
try device.setTorchModeOnWithLevel(brightnessLevel)
}
else if adjustingBrightness && device.torchMode == AVCaptureTorchMode.On {
try device.setTorchModeOnWithLevel(brightnessLevel)
}
} catch {
return false
}
return true
}
The problem I am encountering is that when the timer calls the toggleTorch method, it is passing the value of true as the parameter even though I have specifically passed false to the timer as the userInfo param.
So I scratch my head and think "Ah" let's try using a default value of false in the selector/method parameter and pass nil in the timer userInfo param. That way I can rely on the default value of false being invoked every time. So my new selector signature looks as follows:-
func toggleTorch(adjustingBrightness: Bool = false) -> Bool
And the timer that now calls it has changed to:-
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "toggleTorch:", userInfo: nil, repeats: true)
However, despite the default parameter and no parameter passing going on via the timer, the value being passed through is still true. So I tinker some more and decide to see if using my ViewController as the target object will make a difference. I place a new selector in my ViewController like so:-
func toggleTorch() {
torch.toggleTorch(false)
}
I then update my timer to call this new method within the ViewController :-
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "toggleTorch", userInfo: nil, repeats: true)
'Hey Presto' it now works fine and the correct boolean value of false is being passed because I have passed the value myself. Why is this happening? For info, I'v been learning Swift for about three wks so am no expert
NSTimer does not pass the userInfo information as the parameter to the selector. It passes itself as the parameter so that you know which timer was called.
You should set it up as follows:
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self.torch, selector: "strobeTimerFired:", userInfo: nil, repeats: true)
And have a method as follows in your Torch object:
func strobeTimerFired(timer: NSTimer) {
toggleTorch(false)
}
In this case you don't need to access the timer object in the strobeTimerFired method, but it's good practise to include it anyway (it can be skipped). You could add additional checking to ensure the timer that triggered the method is the one you expected for example.
If you did need to use the userInfo for something, (don't think you'd need it in this case), you could pass an object in the original scheduledTimerWithTimeInterval call as the userInfo parameter, and then you would access that in the strobeTimerFired method by accessing: timer.userInfo.

How to check if a NSTimer is running or not in Swift?

How to check if NSTimer is running or not in Swift. In obj-c the code should be like this as I guess:
if (!myTimer) {
//DO
}
I'm trying to set it in Swift like this and it's showing errors.
if !myTimer {
// DO
}
What I do (in both languages) is to make my timer weak. In swift it would be a weak optional.
weak var myTimer: NSTimer?
Then I create a timer with
myTimer = NSTimer.scheduledTimerWithTimeInterval(1,
target: self,
selector: "timerFired:",
userInfo: nil,
repeats: false)
And then you can use
if timer == nil
to tell if it's running.
To stop the timer you just call
myTimer?.invalidate()
In Objective-C it would be
[myTimer invalidate];
That works in Objective-C because sending messages to nil pointers is valid, and just does nothing.
If you don't want to use a weak optional, you can query a timer to see if it's running by looking at it's valid property.
How about the below option? Can you see if this works for you
if myTimer.valid {
}
if !myTimer.valid {
//DO
}
Swift 4 answer:
if timer.isValid{
}
https://developer.apple.com/documentation/foundation/timer

Resources