如何将NSUrl转换为NSString?

RAG*_*poR 34 cocoa cocoa-touch objective-c ios

之后AVAssetExportSession拥有完整导出视频.我打算通过Youtube上传视频路径.但[GDataUtilities MIMETypeForFileAtPath:path defaultMIMEType:@"video/mp4"]; 它只接受NSString.是否可以将NSUrl转换为NSString用于视频文件路径.

我试着用NSString *path = [ExportoutputURL absoluteString]; 它但崩溃了.

这是守则

- (void)exportDidFinish:(AVAssetExportSession*)session {
    ExportoutputURL = session.outputURL;

    _exporting = NO;
    NSIndexPath *exportCellIndexPath = [NSIndexPath indexPathForRow:2 inSection:kProjectSection];
    ExportCell *cell = (ExportCell*)[self.tableView cellForRowAtIndexPath:exportCellIndexPath];
    cell.progressView.progress = 1.0;
    [cell setProgressViewHidden:YES animated:YES];
    [self updateCell:cell forRowAtIndexPath:exportCellIndexPath];

    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:ExportoutputURL]) {
        [library writeVideoAtPathToSavedPhotosAlbum:ExportoutputURL
                                    completionBlock:^(NSURL *assetURL, NSError *error){
                                        dispatch_async(dispatch_get_main_queue(), ^{
                                            if (error) {
                                                NSLog(@"writeVideoToAssestsLibrary failed: %@", error);
                                                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[error localizedDescription]
                                                                                                    message:[error localizedRecoverySuggestion]
                                                                                                   delegate:nil
                                                                                          cancelButtonTitle:@"OK"
                                                                                          otherButtonTitles:nil];
                                                [alertView show];
                                                [alertView release];
                                            }
                                            else {
                                                _showSavedVideoToAssestsLibrary = YES;
                                                ExportCell *cell = (ExportCell*)[self.tableView cellForRowAtIndexPath:exportCellIndexPath];
                                                [cell setDetailTextLabelHidden:NO animated:YES];
                                                [self updateCell:cell forRowAtIndexPath:exportCellIndexPath];
                                                NSArray *modes = [[[NSArray alloc] initWithObjects:NSDefaultRunLoopMode, UITrackingRunLoopMode, nil] autorelease];
                                                [self performSelector:@selector(hideCameraRollText) withObject:nil afterDelay:5.0 inModes:modes];
                                            }
                                        });

                                    }];
    }
    [library release];
}

- (void)uploadVideoFile {

    NSString *devKey = DEVELOPER_KEY;

    GDataServiceGoogleYouTube *service = [self youTubeService];
    [service setYouTubeDeveloperKey:devKey];

    NSURL *url = [GDataServiceGoogleYouTube youTubeUploadURLForUserID:kGDataServiceDefaultUser];

    // load the file data
    NSString *path = [ExportoutputURL absoluteString];//[[NSBundle mainBundle] pathForResource:@"video_2451" ofType:@"mp4"];//[mFilePathField stringValue];
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
    NSString *filename = [path lastPathComponent];

    // gather all the metadata needed for the mediaGroup
    NSString *titleStr = @"Upload Test";//[mTitleField stringValue];
    GDataMediaTitle *title = [GDataMediaTitle textConstructWithString:titleStr];

    NSString *categoryStr = @"Entertainment";//[[mCategoryPopup selectedItem] representedObject];
    GDataMediaCategory *category = [GDataMediaCategory mediaCategoryWithString:categoryStr];
    [category setScheme:kGDataSchemeYouTubeCategory];

    NSString *descStr = @"GData Description";//[mDescriptionField stringValue];
    GDataMediaDescription *desc = [GDataMediaDescription textConstructWithString:descStr];

    NSString *keywordsStr = @"RAGOpoR Demo";//[mKeywordsField stringValue];
    GDataMediaKeywords *keywords = [GDataMediaKeywords keywordsWithString:keywordsStr];

    BOOL isPrivate = NO;//([mPrivateCheckbox state] == NSOnState);

    GDataYouTubeMediaGroup *mediaGroup = [GDataYouTubeMediaGroup mediaGroup];
    [mediaGroup setMediaTitle:title];
    [mediaGroup setMediaDescription:desc];
    [mediaGroup addMediaCategory:category];
    [mediaGroup setMediaKeywords:keywords];
    [mediaGroup setIsPrivate:isPrivate];

    NSString *mimeType = [GDataUtilities MIMETypeForFileAtPath:path
                                               defaultMIMEType:@"video/mp4"];

    // create the upload entry with the mediaGroup and the file
    GDataEntryYouTubeUpload *entry;
    entry = [GDataEntryYouTubeUpload uploadEntryWithMediaGroup:mediaGroup
                                                    fileHandle:fileHandle
                                                      MIMEType:mimeType
                                                          slug:filename];

    SEL progressSel = @selector(ticket:hasDeliveredByteCount:ofTotalByteCount:);
    [service setServiceUploadProgressSelector:progressSel];

    GDataServiceTicket *ticket;
    ticket = [service fetchEntryByInsertingEntry:entry
                                      forFeedURL:url
                                        delegate:self
                               didFinishSelector:@selector(uploadTicket:finishedWithEntry:error:)];
    [self setUploadTicket:ticket];
    GTMHTTPUploadFetcher *uploadFetcher = (GTMHTTPUploadFetcher *)[ticket objectFetcher];

}
Run Code Online (Sandbox Code Playgroud)

错误EXC_BAD_ACCESS在

NSString *path = [ExportoutputURL absoluteString];
Run Code Online (Sandbox Code Playgroud)

Pet*_*sey 59

是否可以将NSUrl转换为NSString用于视频文件路径.

是.给它absoluteString发消息.

我试着使用NSString*path = [ExportoutputURL absoluteString]; 但它崩溃了.

如果您想要路径,请向URL发送path消息.表示URL的字符串通常不是有效路径; 如果你想要一条路,请问一条路.

至于崩溃,这并不意味着absoluteString错.发送absoluteString到NSURL对象是获取表示URL的NSString对象的正确方法.问题出在其他地方.

错误EXC_BAD_ACCESS在

NSString *path = [ExportoutputURL absoluteString];
Run Code Online (Sandbox Code Playgroud)

这可能意味着ExportoutputURL指向不是nil但不是有效对象的东西.它可能在某个时刻指向了NSURL对象,但现在还没有.

我的猜测是问题是这样的:

ExportoutputURL = session.outputURL;
Run Code Online (Sandbox Code Playgroud)

您将URL分配给ExportoutputURL实例变量,但不保留该对象或创建自己的副本.因此,您不拥有此对象,这意味着您不会将其保持活动状态.它可能随时死亡,很可能在此方法(exportDidFinish:)返回后死亡.

崩溃是因为您uploadVideoFile在URL对象已经死亡之后稍后调用.你仍然有一个指向它的指针,但该对象不再存在,因此向它发送消息 - 任何消息 - 都会导致崩溃.

有三个简单的解决方案:

  1. 将URL对象分配给实例变量时,请保留该URL对象.
  2. 制作您自己的URL对象副本,并将其分配给实例变量.
  3. ExportoutputURL使用strong关键字或copy关键字声明为属性,并将对象分配给属性,而不是实例变量.这将调用属性的setter,如果你合成它或正确实现它,将保留或复制你的URL.

无论哪种方式,你将拥有该对象,这将使它保持活着直到你释放它.因此,当您完成它时(dealloc如果不是更早),您将需要释放它,以便您不会泄漏它.

这一切都假设您没有使用ARC.如果您使用的是Xcode 4.2或更高版本,并且可能需要iOS 4或更高版本,则应将项目迁移到ARC,因为它会使许多事情变得更加简单.如果使用ARC,则不需要保留或复制此对象,这意味着现在迁移到ARC是第四种解决方案(但肯定是更大规模的解决方案).


tru*_*ted 12

使用MiekNepster提到的任何一种absolutePath其他方式.扩展他们的答案,前缀之间的区别.path

NSString* string1 = [url absoluteString]; // @"file:///Users/jackbrown/Music/song name.mp3"
NSString* string2 = [url path]; // @"/Users/jackbrown/Music/song name.mp3"`
Run Code Online (Sandbox Code Playgroud)


Mie*_*iek 11

NSString *path = [[NSString alloc] initWithString:[url path]];  ?
Run Code Online (Sandbox Code Playgroud)