העלאת קבצים באמצעות Cloud Storage בפלטפורמות של Apple

הפקודה Cloud Storage for Firebase מאפשרת להעלות קבצים במהירות ובקלות לדלי Cloud Storage שסופק ומנוהל על ידי Firebase.

יצירת קובץ עזר

כדי להעלות קובץ, קודם צריך ליצור הפניה Cloud Storage למיקום ב-Cloud Storage שאליו רוצים להעלות את הקובץ.

כדי ליצור קובץ עזר, מוסיפים נתיבי צאצא לשורש של קטגוריית האחסון Cloud Storage:

Swift

// Create a root reference
let storageRef = storage.reference()

// Create a reference to "mountains.jpg"
let mountainsRef = storageRef.child("mountains.jpg")

// Create a reference to 'images/mountains.jpg'
let mountainImagesRef = storageRef.child("images/mountains.jpg")

// While the file names are the same, the references point to different files
mountainsRef.name == mountainImagesRef.name            // true
mountainsRef.fullPath == mountainImagesRef.fullPath    // false
    

Objective-C

// Create a root reference
FIRStorageReference *storageRef = [storage reference];

// Create a reference to "mountains.jpg"
FIRStorageReference *mountainsRef = [storageRef child:@"mountains.jpg"];

// Create a reference to 'images/mountains.jpg'
FIRStorageReference *mountainImagesRef = [storageRef child:@"images/mountains.jpg"];

// While the file names are the same, the references point to different files
[mountainsRef.name isEqualToString:mountainImagesRef.name];         // true
[mountainsRef.fullPath isEqualToString:mountainImagesRef.fullPath]; // false
  

אי אפשר להעלות נתונים עם הפניה לקטגוריית Cloud Storage הבסיסית. ההפניה צריכה להפנות לכתובת URL של אתר צאצא.

העלאת קבצים

אחרי שיש לכם הפניה, אתם יכולים להעלות קבצים ל-Cloud Storage בשתי דרכים:

  1. העלאה מנתונים בזיכרון
  2. העלאה מכתובת URL שמייצגת קובץ במכשיר

העלאה מנתונים בזיכרון

השיטה putData:metadata:completion: היא הדרך הפשוטה ביותר להעלות קובץ ל-Cloud Storage. ‫putData:metadata:completion: מקבל אובייקט NSData ומחזיר אובייקט FIRStorageUploadTask, שבו אפשר להשתמש כדי לנהל את ההעלאה ולעקוב אחרי הסטטוס שלה.

Swift

// Data in memory
let data = Data()

// Create a reference to the file you want to upload
let riversRef = storageRef.child("images/rivers.jpg")

// Upload the file to the path "images/rivers.jpg"
let uploadTask = riversRef.putData(data, metadata: nil) { (metadata, error) in
  guard let metadata = metadata else {
    // Uh-oh, an error occurred!
    return
  }
  // Metadata contains file metadata such as size, content-type.
  let size = metadata.size
  // You can also access to download URL after upload.
  riversRef.downloadURL { (url, error) in
    guard let downloadURL = url else {
      // Uh-oh, an error occurred!
      return
    }
  }
}
    

Objective-C

// Data in memory
NSData *data = [NSData dataWithContentsOfFile:@"rivers.jpg"];

// Create a reference to the file you want to upload
FIRStorageReference *riversRef = [storageRef child:@"images/rivers.jpg"];

// Upload the file to the path "images/rivers.jpg"
FIRStorageUploadTask *uploadTask = [riversRef putData:data
                                             metadata:nil
                                           completion:^(FIRStorageMetadata *metadata,
                                                        NSError *error) {
  if (error != nil) {
    // Uh-oh, an error occurred!
  } else {
    // Metadata contains file metadata such as size, content-type, and download URL.
    int size = metadata.size;
    // You can also access to download URL after upload.
    [riversRef downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) {
      if (error != nil) {
        // Uh-oh, an error occurred!
      } else {
        NSURL *downloadURL = URL;
      }
    }];
  }
}];
  

העלאה מקובץ מקומי

אתם יכולים להעלות קבצים מקומיים במכשירים, כמו תמונות וסרטונים מהמצלמה, באמצעות השיטה putFile:metadata:completion:. ‫putFile:metadata:completion: מקבל NSURL ומחזיר FIRStorageUploadTask, שאפשר להשתמש בו כדי לנהל את ההעלאה ולעקוב אחרי הסטטוס שלה.

Swift

// File located on disk
let localFile = URL(string: "path/to/image")!

// Create a reference to the file you want to upload
let riversRef = storageRef.child("images/rivers.jpg")

// Upload the file to the path "images/rivers.jpg"
let uploadTask = riversRef.putFile(from: localFile, metadata: nil) { metadata, error in
  guard let metadata = metadata else {
    // Uh-oh, an error occurred!
    return
  }
  // Metadata contains file metadata such as size, content-type.
  let size = metadata.size
  // You can also access to download URL after upload.
  riversRef.downloadURL { (url, error) in
    guard let downloadURL = url else {
      // Uh-oh, an error occurred!
      return
    }
  }
}
    

Objective-C

// File located on disk
NSURL *localFile = [NSURL URLWithString:@"path/to/image"];

// Create a reference to the file you want to upload
FIRStorageReference *riversRef = [storageRef child:@"images/rivers.jpg"];

// Upload the file to the path "images/rivers.jpg"
FIRStorageUploadTask *uploadTask = [riversRef putFile:localFile metadata:nil completion:^(FIRStorageMetadata *metadata, NSError *error) {
  if (error != nil) {
    // Uh-oh, an error occurred!
  } else {
    // Metadata contains file metadata such as size, content-type, and download URL.
    int size = metadata.size;
    // You can also access to download URL after upload.
    [riversRef downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) {
      if (error != nil) {
        // Uh-oh, an error occurred!
      } else {
        NSURL *downloadURL = URL;
      }
    }];
  }
}];
  

אם רוצים לנהל באופן פעיל את ההעלאה, אפשר להשתמש בשיטות putData: או putFile: ולעקוב אחרי משימת ההעלאה, במקום להשתמש ב-completion handler. מידע נוסף זמין במאמר בנושא ניהול העלאות.

הוספת מטא-נתונים של קובץ

אפשר גם לכלול מטא-נתונים כשמעלים קבצים. המטא-נתונים האלה מכילים מאפיינים אופייניים של מטא-נתונים של קבצים, כמו name, size ו-contentType (שנקרא בדרך כלל סוג MIME). השיטה putFile: מסיקה אוטומטית את סוג התוכן מהסיומת של שם הקובץ NSURL, אבל אפשר לשנות את הסוג שזוהה אוטומטית על ידי ציון contentType במטא-נתונים. אם לא מספקים contentType ו-Cloud Storage לא יכול להסיק ברירת מחדל מסיומת הקובץ, Cloud Storage משתמש ב-application/octet-stream. מידע נוסף על מטא-נתונים של קבצים זמין בקטע שימוש במטא-נתונים של קבצים.

Swift

// Create storage reference
let mountainsRef = storageRef.child("images/mountains.jpg")

// Create file metadata including the content type
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"

// Upload data and metadata
mountainsRef.putData(data, metadata: metadata)

// Upload file and metadata
mountainsRef.putFile(from: localFile, metadata: metadata)
    

Objective-C

// Create storage reference
FIRStorageReference *mountainsRef = [storageRef child:@"images/mountains.jpg"];

// Create file metadata including the content type
FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] init];
metadata.contentType = @"image/jpeg";

// Upload data and metadata
FIRStorageUploadTask *uploadTask = [mountainsRef putData:data metadata:metadata];

// Upload file and metadata
uploadTask = [mountainsRef putFile:localFile metadata:metadata];
  

נהל העלאות

בנוסף להפעלת העלאות, אפשר להשהות, להמשיך ולבטל העלאות באמצעות הפונקציות pause, resume ו-cancel. השיטות האלה מעלות אירועים מסוג pause,‏ resume ו-cancel. ביטול העלאה גורם לכך שההעלאה תיכשל עם שגיאה שמציינת שההעלאה בוטלה.

Swift

// Start uploading a file
let uploadTask = storageRef.putFile(from: localFile)

// Pause the upload
uploadTask.pause()

// Resume the upload
uploadTask.resume()

// Cancel the upload
uploadTask.cancel()
    

Objective-C

// Start uploading a file
FIRStorageUploadTask *uploadTask = [storageRef putFile:localFile];

// Pause the upload
[uploadTask pause];

// Resume the upload
[uploadTask resume];

// Cancel the upload
[uploadTask cancel];
  

מעקב אחר התקדמות ההעלאה

אתם יכולים לצרף משקיפים לFIRStorageUploadTask כדי לעקוב אחרי התקדמות ההעלאה. הוספת צופה מחזירה FIRStorageHandle שאפשר להשתמש בו כדי להסיר את הצופה.

Swift

// Add a progress observer to an upload task
let observer = uploadTask.observe(.progress) { snapshot in
  // A progress event occured
}
    

Objective-C

// Add a progress observer to an upload task
NSString *observer = [uploadTask observeStatus:FIRStorageTaskStatusProgress
                                        handler:^(FIRStorageTaskSnapshot *snapshot) {
  // A progress event occurred
}];
  

אפשר להוסיף את הצופים האלה לאירוע FIRStorageTaskStatus:

אירוע אחד (FIRStorageTaskStatus) שימוש רגיל
FIRStorageTaskStatusResume האירוע הזה מופעל כשהמשימה מתחילה או ממשיכה להעלות, ולרוב משתמשים בו יחד עם האירוע FIRStorageTaskStatusPause.
FIRStorageTaskStatusProgress האירוע הזה מופעל בכל פעם שנתונים מועלים אל Cloud Storage, ואפשר להשתמש בו כדי לאכלס את אינדיקטור התקדמות ההעלאה.
FIRStorageTaskStatusPause האירוע הזה מופעל בכל פעם שההעלאה מושהית, ולרוב משתמשים בו בשילוב עם האירוע FIRStorageTaskStatusResume.
FIRStorageTaskStatusSuccess האירוע הזה מופעל כשהעלאה מסתיימת בהצלחה.
FIRStorageTaskStatusFailure האירוע הזה מופעל כשהעלאה נכשלת. בודקים את השגיאה כדי לגלות את הסיבה לכשל.

כשמתרחש אירוע, מוחזר אובייקט FIRStorageTaskSnapshot. התמונה הזו היא תצוגה קבועה של המשימה, בזמן שהאירוע התרחש. האובייקט הזה מכיל את המאפיינים הבאים:

נכס סוג תיאור
progress NSProgress אובייקט NSProgress שמכיל את התקדמות ההעלאה.
error NSError שגיאה שאירעה במהלך ההעלאה, אם יש כזו.
metadata FIRStorageMetadata במהלך ההעלאה מכיל את המטא-נתונים שמועלים. אחרי אירוע FIRTaskStatusSuccess, מכיל את המטא-נתונים של הקובץ שהועלה.
task FIRStorageUploadTask המשימה שזהו צילום מצב שלה, שאפשר להשתמש בו כדי לנהל את המשימה (pause, resume, cancel).
reference FIRStorageReference ההפניה שממנה הגיעה המשימה.

אפשר גם להסיר משקיפים, בנפרד, לפי סטטוס או על ידי הסרת כולם.

Swift

// Create a task listener handle
let observer = uploadTask.observe(.progress) { snapshot in
  // A progress event occurred
}

// Remove an individual observer
uploadTask.removeObserver(withHandle: observer)

// Remove all observers of a particular status
uploadTask.removeAllObservers(for: .progress)

// Remove all observers
uploadTask.removeAllObservers()
    

Objective-C

// Create a task listener handle
NSString *observer = [uploadTask observeStatus:FIRStorageTaskStatusProgress
                                       handler:^(FIRStorageTaskSnapshot *snapshot) {
  // A progress event occurred
}];

// Remove an individual observer
[uploadTask removeObserverWithHandle:observer];

// Remove all observers of a particular status
[uploadTask removeAllObserversForStatus:FIRStorageTaskStatusProgress];

// Remove all observers
[uploadTask removeAllObservers];
  

כדי למנוע דליפות זיכרון, כל הצופים מוסרים אחרי שמתרחש FIRStorageTaskStatusSuccess או FIRStorageTaskStatusFailure.

טיפול בשגיאות

יכולות להיות כמה סיבות לשגיאות בהעלאה, כולל קובץ מקומי שלא קיים או משתמש שאין לו הרשאה להעלות את הקובץ הרצוי. מידע נוסף על שגיאות זמין בקטע Handle Errors במסמכים.

דוגמה מלאה

בהמשך מוצגת דוגמה מלאה להעלאה עם מעקב אחר ההתקדמות וטיפול בשגיאות:

Swift

// Local file you want to upload
let localFile = URL(string: "path/to/image")!

// Create the file metadata
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"

// Upload file and metadata to the object 'images/mountains.jpg'
let uploadTask = storageRef.putFile(from: localFile, metadata: metadata)

// Listen for state changes, errors, and completion of the upload.
uploadTask.observe(.resume) { snapshot in
  // Upload resumed, also fires when the upload starts
}

uploadTask.observe(.pause) { snapshot in
  // Upload paused
}

uploadTask.observe(.progress) { snapshot in
  // Upload reported progress
  let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
    / Double(snapshot.progress!.totalUnitCount)
}

uploadTask.observe(.success) { snapshot in
  // Upload completed successfully
}

uploadTask.observe(.failure) { snapshot in
  if let error = snapshot.error as? NSError {
    switch (StorageErrorCode(rawValue: error.code)!) {
    case .objectNotFound:
      // File doesn't exist
      break
    case .unauthorized:
      // User doesn't have permission to access file
      break
    case .cancelled:
      // User canceled the upload
      break

    /* ... */

    case .unknown:
      // Unknown error occurred, inspect the server response
      break
    default:
      // A separate error occurred. This is a good place to retry the upload.
      break
    }
  }
}
    

Objective-C

// Local file you want to upload
NSURL *localFile = [NSURL URLWithString:@"path/to/image"];

// Create the file metadata
FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] init];
metadata.contentType = @"image/jpeg";

// Upload file and metadata to the object 'images/mountains.jpg'
FIRStorageUploadTask *uploadTask = [storageRef putFile:localFile metadata:metadata];

// Listen for state changes, errors, and completion of the upload.
[uploadTask observeStatus:FIRStorageTaskStatusResume handler:^(FIRStorageTaskSnapshot *snapshot) {
  // Upload resumed, also fires when the upload starts
}];

[uploadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) {
  // Upload paused
}];

[uploadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) {
  // Upload reported progress
  double percentComplete = 100.0 * (snapshot.progress.completedUnitCount) / (snapshot.progress.totalUnitCount);
}];

[uploadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) {
  // Upload completed successfully
}];

// Errors only occur in the "Failure" case
[uploadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) {
  if (snapshot.error != nil) {
    switch (snapshot.error.code) {
      case FIRStorageErrorCodeObjectNotFound:
        // File doesn't exist
        break;

      case FIRStorageErrorCodeUnauthorized:
        // User doesn't have permission to access file
        break;

      case FIRStorageErrorCodeCancelled:
        // User canceled the upload
        break;

      /* ... */

      case FIRStorageErrorCodeUnknown:
        // Unknown error occurred, inspect the server response
        break;
    }
  }
}];
  

אחרי שהעליתם קבצים, נלמד איך להוריד אותם מ-Cloud Storage.