jueves, 21 de julio de 2016

iOS: Upload image with multipart AFKNetworking 3.0

Objective C

#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
    
    [self.pictureImageView setImage:image];
    
    [self showActivityIndicator];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),  ^{
    
        [[Server sharedInstance] uploadProfileImage:info user:self.user callback:^(ServerResponse *serverResponse) {
            
            [self hideActivityIndicator];
        }];
        
        
    });
}


- (void)uploadProfileImage:(NSDictionary*)imageInfo user:(User*)user callback:(void (^)(ServerResponse* serverResponse))callback
{
    UIImage *image = [imageInfo valueForKey:UIImagePickerControllerOriginalImage];
    NSURL *referenceURL = [imageInfo valueForKey:UIImagePickerControllerReferenceURL];
    
    NSString * ext = [self _extentionFromReferenceURL:[referenceURL absoluteString]];
    
    NSData* data = nil;
    
    if ([ext isEqualToString:@"jpeg"]) {
        data = UIImageJPEGRepresentation(image, 0);

    } else {
        data = UIImagePNGRepresentation(image);
    }
    
    AFJSONRequestSerializer* reqSerializer = [self _newSerializer];
    [reqSerializer setValue: [NSString stringWithFormat:@"JWT %@", [Preferences apiToken]] forHTTPHeaderField:@"Authorization"];
    [reqSerializer setValue:@"multipart/form-data" forHTTPHeaderField:@"Content-Type"];
    [self.netmanager setRequestSerializer:reqSerializer];
    
    [self.netmanager PATCH:[NSString stringWithFormat:@"user-profiles/%@/", user.profile.profileId] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        
        NSString* mimeType = [NSString stringWithFormat:@"image/%@", ext];
        
        [formData appendPartWithFileData:data
                                    name:@"profile_picture"
                                fileName:[NSString stringWithFormat:@"profile-picture.%@", ext] mimeType:mimeType];
        
        // etc.
    } progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
        
        NSLog(@"Response object: %@", responseObject);
        
        [self _checkAndHandleErrorIfAny:responseObject noErrorCallback:^(id response) {
            callback([[ServerResponse alloc] initWithObject:nil]);
            
        } retryCallback:^{
            [self uploadProfileImage:imageInfo user:user callback:callback];
            
        } errorCallback:^(NSError *error) {
            callback([[ServerResponse alloc] initWithError:error]);
        }];
        
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        NSLog(@"Error: %@", error);
        callback([[ServerResponse alloc] initWithError:error]);
    }];


}

Swift

// Using alamofire

func uploadProfilePicture(_ image : UIImage, completion:@escaping(_: Any?)->Void) {
        
        let imageData = UIImageJPEGRepresentation(image , 1)
        
        Alamofire.upload(multipartFormData: { (multipartFormData) in
            multipartFormData.append(imageData!, withName: <parameter_name>, fileName: "swift_file\(arc4random_uniform(100)).jpeg", mimeType: "image/jpeg")
            
            //            for key in parameters.keys{
            //                let name = String(key)
            //                if let val = parameters[name!] as? String{
            //                    multipartFormData.append(val.data(using: .utf8)!, withName: name!)
            //                }
            //            }
        }, to: "\(URLs.addProfilePicture)/0", method: .post, headers: getRequestHeaders()) { (result) in
            switch result {
            case .success(let upload, _, _):
                
                upload.uploadProgress(closure: { (Progress) in
                    print(Progress)
                })
                upload.response(completionHandler: { (response) in
                    print(response)
                })
                
            case .failure(let encodingError):
                completion(nil)
            }
        }

    }

martes, 12 de julio de 2016

iOS: Generate .pem file (push certification)

1) Create a dev and production certificate for push notifications
2) Go to the keychain and look for either the dev or production certificate and export both the certificate and the key (at the same time) and save it to the
3) Open a new terminal:

a)
      cd Desktop
      openssl pkcs12 -in pushcert.p12 -out pushcert.pem -nodes -clcerts

b)
      cd Desktop
      rm pushcert.p12

lunes, 11 de julio de 2016

iOS: Grouping asyn tasks / Grouping server calls

Objective C

dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    [self _someMethodWithCallback::^() {
        
        NSLog(@"Finished 1");
        dispatch_group_leave(group);
    }];

    dispatch_group_enter(group);
     [self _anotherMethodWithCallback::^() {
        
        NSLog(@"Finished 2");
        dispatch_group_leave(group);
    }];
    
    dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
        
        NSLog(@"Finished all");

    });

Swift

   let group: DispatchGroup = DispatchGroup()
   
   // For every endpoint call
   group.enter()
   someMethodWithCallback(onCompletion: {
                group.leave()
                }, onError: { (error) in
                    group.leave()
            })

    …

   group.notify(queue: DispatchQueue.main) {
            onCompletion()
        }