Restkit multipartFormRequestForObject example does not build for me - restkit

My viewController has the following method, which gets called after an image gets selected via a UIImagePickerController. I'd like to upload the selected image to my web service, however, when attempting to follow the samples provided by RestKit I get the following error:
No visible #interface for 'RKObjectManager' declares the selector 'multipartFormRequestForObject:method:path:parameters:constructingBodyWithBlock:'
I'm using the most recent version of restkit, and right clicked went to definition to check the signature which seems correct.
It is worth noting that AFMultipartFormData is not highlighting in XCode. I tried including #import AFNetworking/AFHTTPClient.h but it still shows as plain text, which i suspect might be the problem?
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
image = [info objectForKey:UIImagePickerControllerOriginalImage];
[imageView setImage:image];
ImageRecord *imageRecord = [ImageRecord new];
NSDictionary *params = #{#"param1" : #"value1",
#"param2" : #"value2",
#"param3" : #"value3"};
// Serialize the Article attributes then attach a file
NSMutableURLRequest *request = [[RKObjectManager sharedManager] multipartFormRequestForObject:imageRecord method:RKRequestMethodPOST path:#"stuff" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:UIImagePNGRepresentation(image)
name:#"article[image]"
fileName:#"photo.png"
mimeType:#"image/png"];
}];
RKObjectRequestOperation *operation = [[RKObjectManager sharedManager] objectRequestOperationWithRequest:request success:nil failure:nil];
[[RKObjectManager sharedManager] enqueueObjectRequestOperation:operation]; // NOTE: Must be enqueued rather than started
[self dismissViewControllerAnimated:YES completion:NULL];
}
Thanks for any pointers!

That method is multipartFormRequestWithObject: (note that the method name you're using has ForObject). You shouldn't need to import any additional headers.

Related

UIDocumentInteractionController broken in iOS 8

The related code below worked perfect when i was building for iOS 7, but it seems now in iOS 8, it's not working properly.
By properly, I mean in the sense where it's not actually sending the file or whatever to the chosen app.
Example: If I selected Mail, it would open the mail app with the image or zip I chose in the text field. Now it won't send and it takes forever to call/dismiss the UIDocumentInteractionController.
What am I doing wrong?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
NSString *fileName = [directoryContents objectAtIndex:indexPath.row];
NSString *path;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"Downloads"];
path = [path stringByAppendingPathComponent:fileName];
documentController = [[UIDocumentInteractionController alloc] init];
documentController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]];
[documentController setDelegate:self];
[documentController presentOptionsMenuFromRect:CGRectZero inView:self.view animated:YES];
[documentController retain];
}
I have been playing around with the UIDocumentInteractionController and Delegate trying to fix a similar problem, the controller opened-up alright but selecting an application caused it to close without doing anything, my delegate method documentInteractionControllerDidDismissOpenInMenu also run alright afterwards.
In the console i got the notification enabledRemoteNotificationTypes is not supported in iOS 8.0 and later.
It turns out that this problem will accrue when one of these delegate methods is called :
documentInteractionControllerDidDismissOpenInMenu
documentInteractionControllerDidDismissOptionsMenu
(and possibly others, i did not check all of them)
I did not find any comment in the IOS Development Library or the UIDocumentInteractionController.h about these methods not supported for IOS 8.1 but at this point i cant find any other explanation.
Solution :
i replaced documentInteractionControllerDidDismissOpenInMenu
with didEndSendingToApplication
and it solved the problem for me.

Xcode 4.3.3 : how to assign a view controller while initializing

Hy all.
Since i am using IOS 5 , therefore i am using storyboard.
In the older versions, i could easily write initWithNibName:#"Details", and it worked like a charm.
Now in storyboard, and since i am not using any XIB file, i need to do the same thing.
Here's a snippet of my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the selected country
NSString *selectedAuthors = [theauthors objectAtIndex:indexPath.row];
//Initialize the detail view controller and display it.
Details *dvController = [[Details alloc] initWithNibName:#"Details" bundle:nil];
dvController.selectedAuthors = selectedAuthors;
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
}
My new Snippet :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the selected country
NSString *selectedAuthors = [theauthors objectAtIndex:indexPath.row];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard.storyboard" bundle:nil];
Details *dvController = [storyboard instantiateViewControllerWithIdentifier:#"Details"]; //Or whatever identifier you have defined in your storyboard
//Initialize the detail view controller and display it.
//Details *dvController = [[Details alloc] init/*WithNibName:#"Details" bundle:nil*/];
dvController.selectedAuthors = selectedAuthors;
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
}
Application Log :
2012-07-17 16:30:15.760 AuthorsApp[6534:f803] WARNING: Using legacy cell layout due to delegate implementation of tableView:accessoryTypeForRowWithIndexPath: in <AuthorVC: 0x6857ba0>. Please remove your implementation of this method and set the cell properties accessoryType and/or editingAccessoryType to move to the new cell layout behavior. This method will no longer be called in a future release.
2012-07-17 16:30:16.167 AuthorsApp[6534:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Storyboard (<UIStoryboard: 0x6867750>) doesn't contain a view controller with identifier 'Details''
*** First throw call stack:
(0x1595022 0x1726cd6 0x500fef 0x3151 0x1675c5 0x1677fa 0x9fc85d 0x1569936 0x15693d7 0x14cc790 0x14cbd84 0x14cbc9b 0x147e7d8 0x147e88a 0xd6626 0x1dc2 0x1d35)
terminate called throwing an exception(lldb)
Latest Application Log:
2012-07-17 16:35:15.352 AuthorsApp[6600:f803] WARNING: Using legacy cell layout due to delegate implementation of tableView:accessoryTypeForRowWithIndexPath: in <AuthorVC: 0x688d810>. Please remove your implementation of this method and set the cell properties accessoryType and/or editingAccessoryType to move to the new cell layout behavior. This method will no longer be called in a future release.
2012-07-17 16:35:15.912 AuthorsApp[6600:f803] Everything is ok now !
(lldb)
Final Log
Couldn't register com.test.erc.AuthorsApp with the bootstrap server. Error: unknown error code.
This generally means that another instance of this process was already running or is hung in the debugger.(lldb)
You could instantiate the controller that is located in your storyboard like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"myStoryboard" bundle:nil];
Details *dvController = [storyboard instantiateViewControllerWithIdentifier:#"Details"]; //Or whatever identifier you have defined in your storyboard
Another option since you're using Storyboards would be using segues for the transitions. Here is a nice example. One thing that you get for free with segues is that the destination controller gets instantiated automatically for you. The delegate method looks like this:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"Details"]){
Details *dvController = (Details *)[segue destinationViewController];
// Pass any data to destination controller
// The transition is handled by the segue and defined in the Storyboard ('push' for example)
}
}
EDIT
Here is a screenshot for easy reference:

Cocoa core data project relationship insertion from popup button

I have a core-data with 2 entities: 'CarEntity' and 'PassengerEntity'.
Now, each entity has an attribute called 'name'. CarEntity has a to-many relationship with PassengerEntity called 'passengers' and PassengerEntity has the inverse relationship 'inCar'.
So, I did this interface to insert a new passenger.
I have one NSTextField for the person's name and one NSPopUpButton to chose the car.
The popup button has a "content values" binding to a NSControllerArray that allows me to get all the cars.
Then I have one button to save everything. The header code goes like this:
IBOutlet NSTextField *newPassengerNameField;
IBOutlet NSPopUpButton *newPersonCarField;
And the implementation goes like this:
- (IBAction)saveNewPassenger:(id)sender {
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSManagedObject *newPassengerObject = [
NSEntityDescription
insertNewObjectForEntityForName:#"PassengerEntity"
inManagedObjectContext:managedObjectContext
];
//Here we have all the fields to be inserted.
[newPassengerObject setValue:[newPassengerNameField stringValue] forKey:#"name"];
//Car ?????
}
Okay, this code works just fine.. for the name. But I can't figure out how to insert the car relationship.
My application forces the user to create a car before coming to this stage, so I have objects in the CarEntity.
The question is: How do I get the value of the popup button and send it to this insert code?
Thanks!
This pretty much works, but any help in the sense of cleaning the code is much appreciated!
[newPassengerObject setValue:[newPassengerNameField stringValue] forKey:#"name"];
//Continuing from old code.
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"name = %#", [[newPersonCarField selectedItem] title]];
NSEntityDescription *modelEntity = [NSEntityDescription entityForName:#"CarEntity" inManagedObjectContext:managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:modelEntity];
[fetchRequest setPredicate:predicate];
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
[fetchRequest release];
[newPassengerObject setValue:[results objectAtIndex:0] forKey:#"inCar"];
//Code goes on from here.
// Code cleaning comments
1: Why do you use 'setValue:forKey'? Haven't you auto generated your Entity class files. If you had generated, you could have treated entities like custom objects. For eg. I am picking up your piece of code. It could be modified like below, if you had Entity class files
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
PassengerEntity *newPassengerObject = [
NSEntityDescription
insertNewObjectForEntityForName:#"PassengerEntity"
inManagedObjectContext:managedObjectContext
];
newPassengerObject.name = [newPassengerNameField stringValue];
2: Don't mix up core data code in your saveNewPassenger: method. It was not meant for Core Data operations. In that case, why do you write COre data code inside that method? It will only result in repetition of code. Better write an 'Interface Class' for communicating with Core Data. This will increase modularity and code reusability

Interface Builder: Failing to display TabBarController when calling from TableViewController

A buddy of mine asked for a quick sample of code for an app skeleton that would use a TableView to call a TabView. I estimated an hour.
After more hours than I want to admit messing around in IB, I gave up and implemented the following code.
Can anyone tell me how to do this in IB? I was careful (I thought) to make all the right connections, but no go. I even had another (working) app where I went through and step-by-step made the same connections. I got errors about "Changing the delegate of a tab bar managed by a tab bar controller is not allowed..." (This when I connected the TabBar's delegate to the File's owner, even though another app was working fine with that setting)
Until I wrote this code, I never got the tabbar view, only the view that came with the view xib... (I tested by putting a label on the view).
Thanks in advance...
UITabBarController *tabBarController = [[[UITabBarController alloc] initWithNibName:nil bundle:nil] autorelease];
NumberOneViewController *numberOneViewController = [[[NumberOneViewController alloc] initWithNibName:#"NumberOneViewController" bundle:nil] autorelease];
NumberTwoViewController *numberTwoViewController = [[[NumberTwoViewController alloc] initWithNibName:#"NumberTwoViewController" bundle:nil] autorelease];
NumberThreeViewController *numberThreeViewController = [[[NumberThreeViewController alloc] initWithNibName:#"NumberThreeViewController" bundle:nil] autorelease];
NumberFourViewController *numberFourViewController = [[[NumberFourViewController alloc] initWithNibName:#"NumberFourViewController" bundle:nil] autorelease];
tabBarController.viewControllers = [NSArray arrayWithObjects:numberOneViewController, numberTwoViewController,
numberThreeViewController, numberFourViewController, nil];
[self.navigationController pushViewController:tabBarController animated:YES];
self.view = tabBarController.view; in the viewDidLoad method of the TabBarController delegate class fixed it...
Ah well, surely someone else will run into the same thing and hopefully this will help them...

TTNavigator not opening URLs when clicking on links in TTStyledTextLabels

Trying to make a simple link clicking activity work. I think I understand TTNavigator and TTStyledLabel, but can't get it to work.
Code:
#interface SomeVc : UIViewController <TTNavigatorDelegate> {
IBOutlet TTStyledTextLabel *styledTextLabel;
}
#end
#implementation SomeVc
- (void)viewDidLoad {
[super viewDidLoad];
navigator = [TTNavigator navigator];
navigator.persistenceMode = TTNavigatorPersistenceModeNone;
navigator.delegate = self;
TTURLMap* map = navigator.URLMap;
[map from:#"*" toViewController:[TTWebController class]];
styledTextLabel.text = [TTStyledText textWithURLs:someText];
[navigator openURLAction:[TTURLAction actionWithURLPath:#"http://www.cnn.com/"]];
}
- (BOOL)navigator: (TTNavigator*)navigator shouldOpenURL: (NSURL*)URL {
NSLog(#"trying to open %#", [URL absoluteString]);
return NO;
}
#end
I.e inside a viewcontroller, get the navigator and set self to be its delegate. When a link is opened, the shouldOpenURL delgate method gets called, where I will handle the URL opening myself. (I plan to let navigator handle more of it, but want to get this simple case working first.)
I have a test call at the end of viewDidLoad: which fires the delegate method fine.
Problem: I see the styledTextLabels rendered fine with URL-s, but when I tap on those, nothing happens. They don't reach the TTNavigator for some reason and I can't understand why. Feels like I'm missing some simple connection/scaffolding somewhere, but can't figure it out.
How to make it so that the links tapped in the styledtextlabel will reach the navigator delegate? Or how else should I implement this simple case with styledtextlabel? (just want to get callbacks for url taps.)
try setting the window property :
TTNavigator* navigator = [TTNavigator navigator];
navigator.window = window;
If you don't have one you can add one
navigator.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]
You might also need:
[navigator.window makeKeyAndVisible];

Resources