Seeking an "Exit" Equivalent in Swift

Seeking an exit equivalent in Swift

The exit function isn't a keyword or built-in in C or Objective-C either. It's a library function. In Swift, you can access it by importing Darwin:

import Darwin
exit(0)

Waiting until the task finishes

Use DispatchGroups to achieve this. You can either get notified when the group's enter() and leave() calls are balanced:

func myFunction() {
var a: Int?

let group = DispatchGroup()
group.enter()

DispatchQueue.main.async {
a = 1
group.leave()
}

// does not wait. But the code in notify() gets run
// after enter() and leave() calls are balanced

group.notify(queue: .main) {
print(a)
}
}

or you can wait:

func myFunction() {
var a: Int?

let group = DispatchGroup()
group.enter()

// avoid deadlocks by not using .main queue here
DispatchQueue.global(attributes: .qosDefault).async {
a = 1
group.leave()
}

// wait ...
group.wait()

print(a) // you could also `return a` here
}

Note: group.wait() blocks the current queue (probably the main queue in your case), so you have to dispatch.async on another queue (like in the above sample code) to avoid a deadlock.

Use break into closures [Swift]

Desipte it's very important to know count of images , you can use this

func getImages(_ i:Int) {

let downloadURL = URL(string: "serverURL")
Database.downloadImage(withURL: downloadURL!) { (image) in

if let img = image {

self.imagesArray.append(img)
self.collectionView?.reloadData()
getImages(i+1)

}
else {
print("image is nil final call")
}
}
}
}

Also may be the download is dependent on i as not to make an infinite loop

Swift iOS -CMTimeMakeWithSeconds: warning: error of -0.433 introduced due to very low timescale

I did some research and AVPlayer has a seek method on it:

player.seek(to: <CMTime>, toleranceBefore: <CMTime>, toleranceAfter: <CMTime>)

With this method you can set a tolerance on it to compensate for the truncated overflow which in my situation was the additional -0.433 seconds.

In the first argument you put the time your seeking to and in the second and third arguments you put in kCMTimeZero. Like this:

// seekTime is the time I’m seeking to
player.seek(to: seekTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)

I also followed this answer and the trick was when I initialized my seek time for the second argument I had to put 1000 for everything to work. Like this:

let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)

Here's the code for my fast forward button:

@objc fileprivate func fastForwardButtonTapped() {

guard let playerItem = playerItem else { return }
guard let player = player else { return }

let duration: Float64 = CMTimeGetSeconds(playerItem.duration)
let seekTime: CMTime = CMTimeMakeWithSeconds(duration, 1000)
player.seek(to: seekTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
}

How to make async / await in Swift?

Thanks to vadian's comment, I found what I expected, and it's pretty easy. I use DispatchGroup(), group.enter(), group.leave() and group.notify(queue: .main){}.

func myFunction() {
let array = [Object]()
let group = DispatchGroup() // initialize

array.forEach { obj in

// Here is an example of an asynchronous request which use a callback
group.enter() // wait
LogoRequest.init().downloadImage(url: obj.url) { (data) in
if (data) {
group.leave() // continue the loop
}
}
}

group.notify(queue: .main) {
// do something here when loop finished
}
}

Programmatically change the state of a UILongPressGestureRecognizer

You're getting this error because by default, when you import UIKit into your implementation file, it imports UIGestureRecognizer.h, which publicly declares its state property as readonly. If you want to be able to set this property, you have to import UIGestureRecognizerSubclass.h, which redeclares this property as readwrite. Be warned, this is meant for use within a subclass of UIGestureRecognizer, and I don't know enough about how this works under the hood to say this usage is safe.

#import <UIKit/UIGestureRecognizerSubclass.h>

conversion from NSTimeInterval to hour,minutes,seconds,milliseconds in swift

Swift supports remainder calculations on floating-point numbers, so we can use % 1.

var ms = Int((interval % 1) * 1000)

as in:

func stringFromTimeInterval(interval: TimeInterval) -> NSString {

let ti = NSInteger(interval)

let ms = Int((interval % 1) * 1000)

let seconds = ti % 60
let minutes = (ti / 60) % 60
let hours = (ti / 3600)

return NSString(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)
}

result:

stringFromTimeInterval(12345.67)                   "03:25:45.670"

Swift 4:

extension TimeInterval{

func stringFromTimeInterval() -> String {

let time = NSInteger(self)

let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
let seconds = time % 60
let minutes = (time / 60) % 60
let hours = (time / 3600)

return String(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)

}
}

Use:

self.timeLabel.text = player.duration.stringFromTimeInterval()


Related Topics



Leave a reply



Submit