[英]Upload image from ios device using Firebase - objective c
我是ios開發的新手。 我正在嘗試遵循Firebase的官方文檔來實現圖像上傳功能。 但是我遇到了以下錯誤:
2018-07-20 17:27:43.084497-0700 Geographical_Photo_Map[71118:36381409] -[NSURL _fastCStringContents:]: unrecognized selector sent to instance 0x6040012f2380
2018-07-20 17:27:43.090438-0700 Geographical_Photo_Map[71118:36381409] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSURL _fastCStringContents:]: unrecognized selector sent to instance 0x6040012f2380'
*** First throw call stack:
(
0 CoreFoundation 0x000000011271712b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000011185ef41 objc_exception_throw + 48
2 CoreFoundation 0x0000000112798024 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x0000000112699f78 ___forwarding___ + 1432
4 CoreFoundation 0x0000000112699958 _CF_forwarding_prep_0 + 120
5 libsystem_trace.dylib 0x00000001138ac70b os_log_shim_with_CFString + 66
6 CoreFoundation 0x00000001126ed96f _CFLogvEx3 + 239
7 Foundation 0x000000011088030b _NSLogv + 104
8 Foundation 0x000000011086c023 NSLog + 132
9 Geographical_Photo_Map 0x000000010f119c08 -[ViewController imagePickerController:didFinishPickingMediaWithInfo:] + 216
10 UIKit 0x0000000113e36def -[UIImagePickerController _imagePickerDidCompleteWithInfo:] + 127
11 UIKit 0x0000000113e36709 __60-[UIImagePickerController didSelectMediaWithInfoDictionary:]_block_invoke + 42
12 libdispatch.dylib 0x00000001135c12f7 _dispatch_call_block_and_release + 12
13 libdispatch.dylib 0x00000001135c233d _dispatch_client_callout + 8
14 libdispatch.dylib 0x00000001135cd5f9 _dispatch_main_queue_callback_4CF + 628
15 CoreFoundation 0x00000001126d9e39 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
16 CoreFoundation 0x000000011269e462 __CFRunLoopRun + 2402
17 CoreFoundation 0x000000011269d889 CFRunLoopRunSpecific + 409
18 GraphicsServices 0x0000000117eb99c6 GSEventRunModal + 62
19 UIKit 0x00000001139db5d6 UIApplicationMain + 159
20 Geographical_Photo_Map 0x000000010f11b19f main + 111
21 libdyld.dylib 0x000000011363ed81 start + 1
)
我嘗試調試,現在看來異常發生在此位置:
//NSURL *localFile = [NSURL URLWithString: path];
NSURL *localFile = path;
我嘗試了兩個,但似乎都不起作用。
我的完整代碼:
// This method is called when an image has been chosen from the library or taken from the camera.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//You can retrieve the actual UIImage
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
//Or you can get the image url from AssetsLibrary
NSURL *path = [info valueForKey:UIImagePickerControllerReferenceURL];
[picker dismissViewControllerAnimated:YES completion:nil];
NSLog(@"finish choosing image.");
NSLog(path);
// Upload to firebase
// Local file you want to upload
//NSURL *localFile = [NSURL URLWithString: path];
NSURL *localFile = path;
// Create the file metadata
FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] init];
metadata.contentType = @"image/jpeg";
// Get a reference to the storage service using the default Firebase App
FIRStorage *storage = [FIRStorage storage];
// Create a storage reference from our storage service
FIRStorageReference *storageRef = [storage reference];
// 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;
}
}
}];
}
- (IBAction)UploadButtonClicked:(id)sender {
// Choose from photo library.
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
似乎錯誤是關於NSURL格式的? 但是我認為我使用的參數是NSURL? 如果有人提供任何建議或解決方案,我將不勝感激!
我不知道為什么你使用NSURL
上傳圖片,但你可以使用(我一般用) NSData
直接從產生UIImage
,就像這樣:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
[picker dismissViewControllerAnimated:YES completion:nil];
// Get the selected image.
UIImage *image = [info valueForKey:UIImagePickerControllerEditedImage];
// Generate a data from the image selected
NSData *imageData = UIImageJPEGRepresentation(image, 0.8);
// Create the file metadata
FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] init];
metadata.contentType = @"image/jpeg";
// Get a reference to the storage service using the default Firebase App
FIRStorage *storage = [FIRStorage storage];
// Create a storage reference from our storage service
FIRStorageReference *storageRef = [storage reference];
// Upload file and metadata to the object 'images/mountains.jpg'
FIRStorageUploadTask *uploadTask = [storageRef putData:imageData 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
}];
}
通過這種方式(上圖),您可以進行更改以降低上傳之前圖像的壓縮質量。
無論如何,如果要從選擇器生成所選圖像的本地路徑,則可以使用以下命令:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
[picker dismissViewControllerAnimated:YES completion:nil];
// Get the selected image's NSURL.
NSURL *imagePath = [info objectForKey:@"UIImagePickerControllerReferenceURL"];
NSString *imageName = [imagePath lastPathComponent];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localFilePathString = [documentsDirectory stringByAppendingPathComponent:imageName];
NSURL *localFile = [NSURL URLWithString:localFilePathString];
// Create the file metadata
FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] init];
metadata.contentType = @"image/jpeg";
// Get a reference to the storage service using the default Firebase App
FIRStorage *storage = [FIRStorage storage];
// Create a storage reference from our storage service
FIRStorageReference *storageRef = [storage reference];
// 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
}];
}
所以我敢打賭,您錯誤地生成了本地路徑,因此崩潰了,您給出的路徑包含nil。
我希望這有幫助!
堆棧跟蹤已明確指出是哪條語句導致您的應用崩潰:
0x000000011086c023 NSLog + 132
您誤用了NSLog
函數,如下所示:
NSURL *path = [info valueForKey:UIImagePickerControllerReferenceURL];
[picker dismissViewControllerAnimated:YES completion:nil];
NSLog(@"finish choosing image.");
NSLog(path); // <---- This statement make you crash
您不能直接將NSURL
參數傳遞給NSLog
函數,因為NSLog
是C函數。 NSLog
的原型是:
void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2) NS_NO_TAIL_CALL
要解決此問題,應將其稱為:
NSLog(@"URL: %@", path);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.