------------------------- | Cloud Storage Upload | ------------------------- | [Select Photo] | | | | | | Upload Progress: 0% | | | | [Upload] | -------------------------
Cloud Storage in iOS Swift - Mini App: Build & Ship
import SwiftUI import PhotosUI struct CloudStorageUploadView: View { @State private var selectedImage: UIImage? = nil @State private var isUploading = false @State private var uploadProgress: Double = 0.0 @State private var showConfirmation = false @State private var isPickerPresented = false var body: some View { VStack(spacing: 20) { Text("Cloud Storage Upload") .font(.title) .padding() Button("Select Photo") { // TODO: Present photo picker } .padding() .background(Color.blue) .foregroundColor(.white) .cornerRadius(8) // TODO: Show selected image preview here Text("Upload Progress: \(Int(uploadProgress * 100))%") Button("Upload") { // TODO: Upload selected image } .padding() .background(selectedImage == nil || isUploading ? Color.gray : Color.green) .foregroundColor(.white) .cornerRadius(8) .disabled(selectedImage == nil || isUploading) if showConfirmation { Text("Upload completed successfully!") .foregroundColor(.green) } Spacer() } .padding() } }
import SwiftUI import PhotosUI struct CloudStorageUploadView: View { @State private var selectedImage: UIImage? = nil @State private var isUploading = false @State private var uploadProgress: Double = 0.0 @State private var showConfirmation = false @State private var isPickerPresented = false var body: some View { VStack(spacing: 20) { Text("Cloud Storage Upload") .font(.title) .padding() Button("Select Photo") { isPickerPresented = true showConfirmation = false } .padding() .background(Color.blue) .foregroundColor(.white) .cornerRadius(8) .sheet(isPresented: $isPickerPresented) { PhotoPicker(selectedImage: $selectedImage) } if let image = selectedImage { Image(uiImage: image) .resizable() .scaledToFit() .frame(width: 150, height: 150) .cornerRadius(8) .shadow(radius: 5) } Text("Upload Progress: \(Int(uploadProgress * 100))%") Button("Upload") { startUpload() } .padding() .background(selectedImage == nil || isUploading ? Color.gray : Color.green) .foregroundColor(.white) .cornerRadius(8) .disabled(selectedImage == nil || isUploading) if showConfirmation { Text("Upload completed successfully!") .foregroundColor(.green) } Spacer() } .padding() } func startUpload() { guard selectedImage != nil else { return } isUploading = true uploadProgress = 0.0 showConfirmation = false // Simulate upload with timer Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in uploadProgress += 0.05 if uploadProgress >= 1.0 { timer.invalidate() isUploading = false showConfirmation = true } } } } struct PhotoPicker: UIViewControllerRepresentable { @Binding var selectedImage: UIImage? func makeUIViewController(context: Context) -> PHPickerViewController { var config = PHPickerConfiguration() config.filter = .images config.selectionLimit = 1 let picker = PHPickerViewController(configuration: config) picker.delegate = context.coordinator return picker } func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {} func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, PHPickerViewControllerDelegate { let parent: PhotoPicker init(_ parent: PhotoPicker) { self.parent = parent } func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { picker.dismiss(animated: true) guard let provider = results.first?.itemProvider else { return } if provider.canLoadObject(ofClass: UIImage.self) { provider.loadObject(ofClass: UIImage.self) { image, _ in DispatchQueue.main.async { self.parent.selectedImage = image as? UIImage } } } } } }
This solution uses SwiftUI with PHPickerViewController to let users pick a photo from their device. The selected photo is shown as a preview image below the Select Photo button.
The Upload button is disabled if no photo is selected or if an upload is in progress. When Upload is tapped, a timer simulates upload progress by increasing a progress value every 0.1 seconds. The progress percentage is shown as text.
When upload completes, a confirmation message appears. The photo picker is presented as a sheet. This approach keeps UI responsive and simple for beginners.
------------------------- | Cloud Storage Upload | ------------------------- | [Select Photo] | | | | [Image Preview] | | Upload Progress: 75% | | | | [Upload] | | | | Upload completed | | successfully! | -------------------------
Practice
What is the main purpose of Cloud Storage in an iOS app?
Solution
Step 1: Understand Cloud Storage role
Cloud Storage is designed to save files online so users can access and share them easily.Step 2: Compare options
Options B, C, and D describe other app functions unrelated to Cloud Storage.Final Answer:
To save files online for easy access and sharing -> Option CQuick Check:
Cloud Storage = Online file saving [OK]
- Confusing Cloud Storage with local storage
- Thinking it manages UI or navigation
- Assuming it stores app settings only
Which of the following is the correct way to create a reference to a file named image.png in Firebase Cloud Storage using Swift?
let storage = Storage.storage() let storageRef = ...
Solution
Step 1: Recall Firebase Storage syntax
To get a reference, use storage.reference() then child("filename") to point to the file.Step 2: Check each option
storageRef = storage.reference().child("image.png") correctly chains reference() and child(). Options B, C, and D use incorrect method calls or syntax.Final Answer:
storageRef = storage.reference().child("image.png") -> Option BQuick Check:
Use reference().child() to get file reference [OK]
- Calling child() directly on storage
- Using Storage.reference() instead of storage.reference()
- Passing filename directly to reference()
What will be printed if the following Swift code successfully uploads a file to Firebase Storage?
let storageRef = Storage.storage().reference().child("file.txt")
let localFile = URL(fileURLWithPath: "/path/to/file.txt")
storageRef.putFile(from: localFile, metadata: nil) { metadata, error in
if let error = error {
print("Upload failed: \(error.localizedDescription)")
} else {
print("Upload succeeded")
}
}Solution
Step 1: Analyze the completion handler
The closure checks if error is nil; if so, it prints "Upload succeeded".Step 2: Given successful upload
Since upload is successful, error is nil, so the else block runs printing "Upload succeeded".Final Answer:
Upload succeeded -> Option AQuick Check:
Success means error is nil, print "Upload succeeded" [OK]
- Assuming error is always non-nil
- Confusing success and failure blocks
- Ignoring the asynchronous completion handler
Identify the error in this Swift code snippet for uploading a file to Firebase Storage:
let storageRef = Storage.storage().reference().child("doc.pdf")
let fileURL = URL(string: "/documents/doc.pdf")!
storageRef.putFile(from: fileURL, metadata: nil) { metadata, error in
if error != nil {
print("Upload error")
} else {
print("Upload complete")
}
}Solution
Step 1: Check URL creation method
URL(string:) is for web URLs; local file paths need URL(fileURLWithPath:).Step 2: Identify impact
Using URL(string:) with a local path returns nil or incorrect URL, causing upload failure.Final Answer:
Using URL(string:) instead of URL(fileURLWithPath:) -> Option AQuick Check:
Local file URLs need URL(fileURLWithPath:) [OK]
- Using URL(string:) for local files
- Forgetting to unwrap optional URLs safely
- Ignoring completion handler errors
You want to upload multiple images to Firebase Cloud Storage and keep track of their download URLs for later use. Which approach correctly handles this in Swift?
let images = [URL(fileURLWithPath: "/img1.png"), URL(fileURLWithPath: "/img2.png")]
var downloadURLs: [URL] = []
for imageURL in images {
let ref = Storage.storage().reference().child(imageURL.lastPathComponent)
ref.putFile(from: imageURL, metadata: nil) { metadata, error in
if error == nil {
ref.downloadURL { url, error in
if let url = url {
downloadURLs.append(url)
}
}
}
}
}
print(downloadURLs)Solution
Step 1: Understand asynchronous behavior
Uploads and downloadURL calls run asynchronously, so print(downloadURLs) runs before completion.Step 2: Effect on printed output
Because of async calls, downloadURLs is likely empty when printed immediately after the loop.Final Answer:
This code may print an empty array because uploads are asynchronous -> Option DQuick Check:
Async uploads delay URL collection, print runs too early [OK]
- Expecting synchronous behavior from async uploads
- Printing results before upload completion
- Not using dispatch groups or async-await to wait
Ready to prove it?
Pass the test and this pattern moves unknown
