Search code examples
iosswiftfunctionloopsnsdate

Swift iOS -Can a Loop Run Faster then Date Secs generated by Date().timeIntervalSince1970


I pull some data from Firebase, add the data to a loop, then print the secs as each loop is ran. Is there a chance that the loop will run so fast that it will print the same secs twice?

For e.g. in the code below is this outcome possible?

image0__1507792099
image1__1507793000
image2__1507793001
image3__1507793001
image4__1507793002
image5__1507793002

Can both image2 and image3 get printed with the same time stamp and can the same thing happen with image4 and image5?

var images:[String] = []
let secs = Int(Date().timeIntervalSince1970)

myRef?.observeSingleEvent(of: .value, with: { 
     (snapshot) in

     if let dict = snapshot.value as? [String:Any]{

          let image0 = dict["image0"] as? String
          let image1 = dict["image1"] as? String
          let image2 = dict["image2"] as? String
          let image3 = dict["image3"] as? String
          let image4 = dict["image4"] as? String
          let image5 = dict["image5"] as? String

          self.images.append(image0)
          self.images.append(image1)
          self.images.append(image2)
          self.images.append(image3)
          self.images.append(image4)
          self.images.append(image5)

         for image in self.images{
             print("\(image)__\(self.secs)")
             let x = someConversionMethodThatReturnsAnImage(str: image)
             saveData(image: x)
         }
     }
}

fileprivate func saveData(image: UIImage){
        let imageExt = String(describing: secs).appending(".jpg")
        let fileManager = FileManager.default
        let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL
        let imagePath = documentsPath.appendingPathComponent(imageExt)?.path
        let data = UIImageJPEGRepresentation(image, 0.8)
        fileManager.createFile(atPath: imagePath!, contents: data, attributes: nil)
    }

FYI the reason I'm asking this question is because I'm using the secs as an extension to add the Firebase data to the DocumentsDirectory. Everything has been working fine but I'm not sure if there can be an overlap in time which means some of the data that is pulled and saved will be overwritten if they both have the same time stamp. I was pondering using arc4Random instead.


Solution

  • Although you certainly can use a timestamp to make filenames unique I wouldn't do it. Even if it works right now circumstances may change down the line, making the loop run faster and causing you to lose data because you create two files during the same quanta. There's also factors such as clocks changing due to daylight savings or other adjustments. I would avoid that chance completely by using a method that is much safer: using a UUID.

    A UUID is a series of values that are designed to be as unique as possible, either through an algorithm or through random means. They are much safer than a timestamp or a value generated through arc4Random and they have the additional benefit of being self-documenting in your code. When you see the UUID struct you know at a glance that you are creating a unique identifier.

    Apple's UUID uses RFC 4122 version 4 which has 5.3x10^36 possible values, leaving the chances of collisons to be infinitesimal.

    You can replace this line:

        let imageExt = String(describing: secs).appending(".jpg")
    

    with this:

        let imageExt = UUID().uuidString.appending(".jpg")