2011-12-08 1 views
10

RestKit을 사용하여 웹 서버와의 상호 작용을 유도합니다. POST에 라우팅을 사용하여 이미지 객체가 첨부 된 서버에 이벤트 객체를 보내려고합니다. 다음과 같이 코드는 : 나는 직렬화 된 이벤트 객체를 사용 RKParams의 인스턴스를 만드는 경우RestKit 이미지 업로드

RKObjectManager *manager = [RKObjectManager sharedManager]; 

    RKObjectMapping *map = [self eventMapping]; 
    manager.serializationMIMEType = RKMIMETypeFormURLEncoded; 
    map.rootKeyPath = @"event"; 
    [manager.mappingProvider setSerializationMapping:map forClass:[Event class]]; 
    [manager.router routeClass:[Event class] toResourcePath:@"/v1/events.json" forMethod:RKRequestMethodPOST]; 

    [manager postObject:event delegate:self block:^(RKObjectLoader *loader){ 
    RKObjectMapping *serMap = [[[RKObjectManager sharedManager] mappingProvider] serializationMappingForClass:[Event class]]; 
    NSError *error = nil; 
    NSDictionary *d = [[RKObjectSerializer serializerWithObject:event mapping:serMap] serializedObject:&error]; 

    RKParams *p = [RKParams paramsWithDictionary:d]; 
    [p setData:[event imageData] MIMEType:@"image/jpeg" forParam:@"image"]; 
    loader.params = p; 
    }]; 

, 다음 이미지 데이터를 추가하고 RKObjectLoader의 PARAMS 특성으로 지정, 모든 속성은 하나 개의 거대한 직렬화 된 문자열이된다. 거대한 문자열 직렬화없이 이미지를 업로드 할 수있는 방법이 있어야합니다.

또한 UMSmage를 NSData로 변환하면서 일부 속성에 매핑되는 NSData 속성을 사용하려고 시도했지만 RestKit은 매핑 할 수 없다고 불평합니다. 누구든지 전에 이것을 했습니까?

답변

16

나는 아주 비슷한 것을했고 그것은 정상적으로 작동했습니다. 귀하의 질문에 대한 RKObjectSerializer가 당신이 기대하는 방식으로 작동하지 않는 이유에 대해 알고 있지만 어쩌면 그것은 당신의 설정과 다른 것입니다. 작동하는 무언가를 깨끗하게 보여주기 위해 코드를 게시하고 있습니다. 즉, RKObjectSerializer 설명서를 읽은 후 RKParams를 직접 설정하지 않고 왜 내 예제 에서처럼 초기화 할 수 없었는지 알 수 없습니다.

라우터 설정 :

RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:kApiUrlBase]; 
[objectManager.router routeClass:[PAPetPhoto class] toResourcePath:@"/pet/uploadPhoto" forMethod:RKRequestMethodPOST]; 

매핑 설정 :

RKObjectMapping *papetPhotoMapping = [RKObjectMapping mappingForClass:[PAPetPhoto class]]; 
[papetPhotoMapping mapKeyPath:@"id" toAttribute:@"identifier"]; 
[papetPhotoMapping mapAttributes:@"accountId", @"petId", @"photoId", @"filename", @"contentType", nil]; 
[objectManager.mappingProvider addObjectMapping:papetPhotoMapping]; 
[objectManager.mappingProvider setSerializationMapping:[papetPhotoMapping inverseMapping] forClass:[PAPetPhoto class]]; 
[objectManager.mappingProvider setMapping:papetPhotoMapping forKeyPath:@"petPhoto"]; 

는 포스트 : 나는이 블록 내 모든 PARAMS을 구축하기 때문에는 (공지 내 목적은 단지입니다 올바른 라우팅 및 매퍼를 트리거하는 더미 인스턴스).

PAPetPhoto *photo = [[PAPetPhoto alloc] init]; 
    [[RKObjectManager sharedManager] postObject:photo delegate:self block:^(RKObjectLoader *loader){ 

     RKParams* params = [RKParams params]; 
     [params setValue:pet.accountId forParam:@"accountId"]; 
     [params setValue:pet.identifier forParam:@"petId"]; 
     [params setValue:_photoId forParam:@"photoId"]; 
     [params setValue:_isThumb ? @"THUMB" : @"FULL" forParam:@"photoSize"]; 
     [params setData:data MIMEType:@"image/png" forParam:@"image"]; 

     loader.params = params; 
    }]; 

서버 엔드 포인트 (자바, 스프링 MVC)

@RequestMapping(value = "/uploadPhoto", method = RequestMethod.POST) 
    @ResponseBody 
    public Map<String, Object> handleFormUpload(@RequestParam("accountId") String accountId, 
            @RequestParam("petId") String petId, 
            @RequestParam("photoId") String photoId, 
            @RequestParam("photoSize") PhotoSizeEnum photoSize, 
            @RequestParam("image") Part image) throws IOException { 

     if (log.isTraceEnabled()) 
      log.trace("uploadPhoto. accountId=" + accountId + " petId=" + petId + " photoId=" + photoId + " photoSize=" + photoSize); 

     PetPhoto petPhoto = petDao.savePetPhoto(accountId, petId, photoId, photoSize, image); 

     Map<String, Object> map = GsonUtils.wrapWithKeypath(petPhoto, "petPhoto"); 
     return map; 
    } 

서버 응답 JSON (주 매핑 설정에 해당하는 "petPhoto"의 키 패스) :

{ 
    petPhoto =  { 
     accountId = 4ebee3469ae2d8adf983c561; 
     contentType = "image/png"; 
     filename = "4ebee3469ae2d8adf983c561_4ec0983d036463d900841f09_3FED4959-1042-4D8B-91A8-76AA873851A3"; 
     id = 4ee2e80203646ecd096d5201; 
     petId = 4ec0983d036463d900841f09; 
     photoId = "3FED4959-1042-4D8B-91A8-76AA873851A3"; 
    }; 
} 

대리인 :

- (void) objectLoader:(RKObjectLoader*)objectLoader didLoadObject:(id)object { 

    if ([objectLoader wasSentToResourcePath:@"/pet/uploadPhoto"]) { 
     PAPetPhoto *photo = (PAPetPhoto*)object; 
    } 
} 
+1

완벽하게 작동합니다! 한 가지주의 사항 : RKObjectMapping의 rootKeyPath 속성을 설정하여 "이벤트"에 이르기까지 모든 것을 스코프하려고하면 더 이상 작동하지 않는 것 같습니다. – Jacob

+0

iOS 6에서이 기능이 작동합니까? "RestKit에 요청시 새 본문 스트림을 다시 전송하라는 요청을 받았습니다. 가능한 연결 오류 또는 인증 시도가 있습니까?" –