Reputation: 89
I am trying to access the value of "x" in nested loop but each time i try this the value of "x" in inner loop it gets varied.
var downloads_array = [[URL]]()//edited
func downloadImages(){
var count = images.count
let storage = Storage.storage().reference()
for x in 0...count-1{
var anime = [String]()
anime.append(images[x])
anime.append(images[x] + "1")
print("outside the second loop x is : \(x)")
for i in anime{
let storageRef = storage.child("images/\(i).jpg")
storageRef.downloadURL { (url, error) in
if let error = error{
print(error.localizedDescription)
}
else{
print(x)
self.downloads_array[x].append(url!)//edited
}
}
}
}
}
The ouput is:
outside the second loop x is : 0
outside the second loop x is : 1
outside the second loop x is : 2
outside the second loop x is : 3
outside the second loop x is : 4
outside the second loop x is : 5
0
3
0
1
1
4
2
5
3
4
2
5
I am new to swift development please guide me in solving this issue.
Upvotes: 0
Views: 409
Reputation: 89
As the Firebase Storage was an Asynchronous call(network call), We can't retain the value as the order will be non-sequential. So i Created a dictionary with String and URL to store the respective download URL for the image
Upvotes: 0
Reputation: 3526
Not sure exactly what you need but I think you're trying to implement something like this : -
func downloadImages(){
var count = images.count
let storage = Storage.storage().reference()
var data : [String:Int] = []
for x in 0...count-1{
var anime = [String]()
anime.append(images[x])
anime.append(images[x] + "1")
print("outside the second loop x is : \(x)")
for i in anime {
let storageRef = storage.child("images/\(i).jpg")
data["YourUrl"] = x // Replace YourUrl with your url string
storageRef.downloadURL { (url, error) in
if let error = error{
print(error.localizedDescription)
}
else{
if let value = data[url.absoluteString]{
print(value)
}
}
}
}
}
}
Upvotes: 1
Reputation: 17054
storageRef.downloadURL
is async
so the code will continue executing and x
value will change. The solution here is to capture the current x value either through an intermediary variable or though block capture
var downloads_array = [[URL]]()//edited
func downloadImages(){
var count = images.count
let storage = Storage.storage().reference()
for x in 0...count-1{
var anime = [String]()
anime.append(images[x])
anime.append(images[x] + "1")
print("outside the second loop x is : \(x)")
for i in anime{
let storageRef = storage.child("images/\(i).jpg")
storageRef.downloadURL { [x] (url, error) in // block capture
if let error = error{
print(error.localizedDescription)
}
else{
print(x)
self.downloads_array[x].append(url!)//edited
}
}
}
}
}
-
var downloads_array = [[URL]]()//edited
func downloadImages(){
var count = images.count
let storage = Storage.storage().reference()
for x in 0...count-1{
var anime = [String]()
anime.append(images[x])
anime.append(images[x] + "1")
print("outside the second loop x is : \(x)")
for i in anime{
let storageRef = storage.child("images/\(i).jpg")
let currentX = x // intermediary variable
storageRef.downloadURL { (url, error) in
if let error = error{
print(error.localizedDescription)
}
else{
print(currentX)
self.downloads_array[currentX].append(url!)//edited
}
}
}
}
}
Upvotes: 2
Reputation: 11242
Your storageRef.downloadURL
is an async call, which means it will take time for the completion block to be executed. The for
loop would be executed and count
* 2 calls would be hit. Depending on how fast each response is received the appropriate completion is called resulting in the order that you are getting.
func downloadImages(){
var count = images.count
let storage = Storage.storage().reference()
for x in 0...count-1{
var anime = [String]()
anime.append(images[x])
anime.append(images[x] + "1")
print("outside the second loop x is : \(x)")
print(x) // printing it here will give you the order as is
for i in anime {
let storageRef = storage.child("images/\(i).jpg")
storageRef.downloadURL { (url, error) in
if let error = error{
print(error.localizedDescription)
}
else{
print(x)
}
}
}
}
}
Since you do not have control over the order in which the completion block is executed. A dictionary would be one solution to your problem. Store the index as the key and url array as the value. Or you could have a struct which stores the urls for the corresponding index and sort it.
Upvotes: 2