Как преобразовать NSUrl в NSString? - PullRequest
34 голосов
/ 15 января 2012

После AVAssetExportSession завершено экспорт видео. Я планирую одеть Video Path для загрузки через 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];

}

Ошибка EXC_BAD_ACCESS в

NSString *path = [ExportoutputURL absoluteString];

Ответы [ 5 ]

59 голосов
/ 15 января 2012

Возможно ли преобразовать NSUrl в NSString для пути к видеофайлу.

Да. Отправьте сообщение absoluteString.

Я пытаюсь использовать NSString * path = [ExportoutputURL absoluteString]; но это сбой.

Если вы хотите указать путь, отправьте URL-адрес path. Строка, представляющая URL, обычно не является допустимым путем; если вы хотите путь, попросите его.

Что касается сбоя, это не значит, что absoluteString не так. Отправка absoluteString объекту NSURL является правильным способом получения объекта NSString, который представляет URL-адрес. Проблема в другом.

Ошибка EXC_BAD_ACCESS в

NSString *path = [ExportoutputURL absoluteString];

Это, вероятно, означает, что ExportoutputURL указывает на то, что не является nil, но также не является допустимым объектом. В какой-то момент он мог указывать на объект NSURL, но сейчас это не так.

Думаю, проблема в следующем:

ExportoutputURL = session.outputURL;

Вы присваиваете URL переменной экземпляра ExportoutputURL, но не сохраняете объект и не создаете свою собственную копию. Следовательно, вы не владеете этим объектом, что означает, что вы не поддерживаете его. Он может умереть в любое время, скорее всего, после того, как этот метод (exportDidFinish:) вернется.

Сбой из-за того, что вы вызываете uploadVideoFile позже, после того, как объект URL уже умер. У вас все еще есть указатель на него, но этот объект больше не существует, поэтому отправка ему сообщения - любое сообщение - вызывает сбой.

Существует три простых решения:

  1. Сохраните объект URL при назначении его переменной экземпляра.
  2. Создайте свою собственную копию объекта URL и назначьте ее переменной экземпляра.
  3. Объявите ExportoutputURL как свойство с ключевым словом strong или ключевым словом copy и назначьте объект свойству , а не переменной экземпляра. Это вызовет установщик свойства, который, если вы его синтезируете или правильно реализуете, сохранит или скопирует для вас URL.

В любом случае, вы будете владеть объектом, и это будет поддерживать его, пока вы не отпустите его. Соответственно, вам нужно будет выпустить его, когда вы закончите с ним (в dealloc, если не раньше), чтобы вы не пропустили его.

Все это предполагает, что вы не используете ARC. Если вы используете Xcode 4.2 или более позднюю версию, и вам может потребоваться iOS 4 или более поздняя версия, вы должны перенести свой проект в ARC, поскольку это значительно упрощает многие вещи. Вам не нужно было бы сохранять или копировать этот объект, если вы использовали ARC, что означает, что переход на ARC теперь является четвертым решением (но, безусловно, более масштабным).

12 голосов
/ 08 января 2015

Используйте либо absolutePath, либо path, как указано Miek и Nepster . Развивая свои ответы, разница между ними заключается в префиксе.

NSString* string1 = [url absoluteString]; // @"file:///Users/jackbrown/Music/song name.mp3"
NSString* string2 = [url path]; // @"/Users/jackbrown/Music/song name.mp3"`
11 голосов
/ 06 апреля 2013
NSString *path = [[NSString alloc] initWithString:[url path]];  ?
0 голосов
/ 10 апреля 2018

Используйте это.Я думаю, что это поможет вам.

В объективе c

NSString *testString = testUrl.absoluteString;

В Swift

var testString : String = testUrl.absoluteString
0 голосов
/ 14 октября 2014

Просто вы можете сделать это так.

NSString *myString = [myURL absoluteString];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...