我是 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)imagePickerControllerUIImagePickerController *)picker didFinishPickingMediaWithInfoNSDictionary *)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)UploadButtonClickedid)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?如果有人提供任何建议或解决方案,我将不胜感激!
Best Answer-推荐答案 strong>
我不确定你为什么使用 NSURL 来上传图片,但你可以使用(我通常使用)直接从 生成的 NSData UIImage ,像这样:
- (void)imagePickerControllerUIImagePickerController *)picker didFinishPickingMediaWithInfoNSDictionary<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)imagePickerControllerUIImagePickerController *)picker didFinishPickingMediaWithInfoNSDictionary<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。
我希望这会有所帮助!
关于ios - 使用 Firebase 从 ios 设备上传图像 - objective-c ,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/51451859/
|