העלאת קבצים באמצעות 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: ולעקוב אחרי משימה ההעלאה, במקום להשתמש בטיפול בהשלמה. למידע נוסף, ראו ניהול העלאות.

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

אפשר גם לכלול מטא-נתונים כשאתם מעלים קבצים. המטא-נתונים האלה מכילים מאפיינים אופייניים של מטא-נתונים של קבצים, כמו 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
FIRStorageHandle observer = [uploadTask observeStatus:FIRStorageTaskStatusProgress
                                              handler:^(FIRStorageTaskSnapshot *snapshot) {
                                                // A progress event occurred
                                              }];
  

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

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

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

נכס סוג תיאור
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
FIRStorageHandle 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.

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

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

דוגמה מלאה

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

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.