I use firebase push notification and OTP, android is working success, when I removed AppDelegate.m in didRegisterForRemoteNotificationsWithDeviceToken and didReceiveRemoteNotification codes , OTP is working success but push notification is going everybody
(void) application:(UIApplication *) application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *) deviceToken {
[[FIRAuth auth] setAPNSToken:deviceToken type:FIRAuthAPNSTokenTypeProd];
self.userId = [[NSUserDefaults standardUserDefaults] valueForKey:#"userId"];
if (self.userId != nil)
{
if (deviceToken != nil)
{
NSLog(#"deviceToken: %#", [self stringWithDeviceToken:deviceToken] );
[FIRMessaging messaging].APNSToken = deviceToken;
[[FIRMessaging messaging] subscribeToTopic:[NSString stringWithFormat:#"%#", self.userId]
completion:^(NSError * _Nullable error) {
NSLog(#"Subscribed to %# topic", [NSString stringWithFormat:#"%#", self.userId]);
}];
}
else
{
NSLog(#"Error registering for notifications: Device Token is Nill");
}
}
else
{
NSLog(#"registerPushNotifications Data Nil!");
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(#"Push received: %#", userInfo);
NSString *title;
NSString *body;
NSString *pushType;
NSString *pushTypeId;
if (userInfo[#"aps"]){
NSDictionary *aps = userInfo[#"aps"];
if (aps[#"alert"]){
NSObject *alert = aps[#"alert"];
if ([alert isKindOfClass:[NSDictionary class]]){
NSDictionary *alertDict = aps[#"alert"];
if (alertDict[#"title"]){
title = alertDict[#"title"];
}
if (alertDict[#"body"]){
body = alertDict[#"body"];
}
}
}
}
if (userInfo[#"type"]){
pushType = userInfo[#"type"];
}
NSDictionary *dict = #{ #"type" : pushType};
if ( application.applicationState == UIApplicationStateActive ){
else {
[NotificationListenerModule emitEventWithName:#"notificationListener" andPayload:dict];
}
}
Related
I had integrated VoIP and remote notification in my app, but Specifically, in iPhone 5s with ios 12.4.5. I did get a VoIP token or remote token. UIApplicationDelegate's toke method and PKPushRegistryDelegate's token method not invoke. what's wrong here I already tried with a strong network of cellular instead of connecting with wifi. and other variants of the iPhone like iPhone 6 and iPhone XR working fine. Please help me with this issue.
I had used a push notification certificate with mention below for both remote and VoIP push.
here is my code
#interface AppDelegate : UIResponder <UIApplicationDelegate,PKPushRegistryDelegate,UNUserNotificationCenterDelegate>
{
PKPushRegistry *voipRegistry;
}
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self pushNotificationRegister];
return true;
}
-(void)pushNotificationRegister
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
UNAuthorizationOptions options = UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge;
center.delegate = self;
[center requestAuthorizationWithOptions:options completionHandler:^(BOOL granted, NSError * _Nullable error){
if( !error ){
dispatch_async(dispatch_get_main_queue(), ^{
[self voipRegistration];
[UIApplication.sharedApplication registerForRemoteNotifications];
});
}
}];
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus != UNAuthorizationStatusAuthorized) {
}
}];
}
- (void) voipRegistration
{
voipRegistry = [[PKPushRegistry alloc] initWithQueue: dispatch_get_main_queue()];
voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
voipRegistry.delegate = self;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
// Not invoke
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
// Not invoke
}
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)pushCredentials forType:(PKPushType)type
{
// Not invoke
}
- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type
{
// Not invoke
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler
{
completionHandler();
}
#end
Is it possible to save video and add it to custom ALAsset, captured from UIImagePicker in mp4 format? Or I have to save it in .mov and make compression by AVAssetExportSession?
Yes, you can compress video using AVAssetExportSession. Here you can specify video type, quality and output url for compress video.
See below methods:
- (void) saveVideoToLocal:(NSURL *)videoURL {
#try {
NSArray *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [documentsDirectory objectAtIndex:0];
NSString *videoName = [NSString stringWithFormat:#"sampleVideo.mp4"];
NSString *videoPath = [docPath stringByAppendingPathComponent:videoName];
NSURL *outputURL = [NSURL fileURLWithPath:videoPath];
NSLog(#"Loading video");
[self convertVideoToLowQuailtyWithInputURL:videoURL outputURL:outputURL handler:^(AVAssetExportSession *exportSession) {
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
NSLog(#"Compression is done");
}
[self performSelectorOnMainThread:#selector(doneCompressing) withObject:nil waitUntilDone:YES];
}];
}
#catch (NSException *exception) {
NSLog(#"Exception :%#",exception.description);
[self performSelectorOnMainThread:#selector(doneCompressing) withObject:nil waitUntilDone:YES];
}
}
//---------------------------------------------------------------
- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL outputURL:(NSURL*)outputURL handler:(void (^)(AVAssetExportSession*))handler {
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetPassthrough];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
handler(exportSession);
}];
}
Here I saved compress video to document directory of application. You can check detail working of this in below sample code:
Sample demo:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
picker.dismiss(animated: true, completion: nil)
guard let mediaType = info[UIImagePickerControllerMediaType] as? String else
{
return
}
if mediaType == "public.movie"
{
if let videoURL = info[UIImagePickerControllerMediaURL] as? URL
{
var videoData:Data!
do {
videoData = try Data(contentsOf: videoURL, options: [Data.ReadingOptions.alwaysMapped])
}
catch
{
print(error.localizedDescription)
return
}
if videoData != nil
{
let writePath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("vid1.mp4")
print("writePath - \(writePath)")
do{
try videoData.write(to: writePath)
}catch{
print("Error - \(error.localizedDescription)")
}
}
}
}
}
I'm trying to get updates from my server. I want it to have the latest information though so I'm running a page and if the response is "Complete" and not "Error" then I will proceed with the Update methods to get the latest information from the xml file. My problem is the Delegate methods are not getting called until all my code in my "Main" function is completed. By that time the code has already gone past my if statement checking if the responseSuccess is TRUE or FALSE. I think its because the NSURLConnection is asynchronous... yet im not sure how to fix it. If I need to provide more code/information just let me know. Thanks!
Main
if (UpdatingFlag)
{
NSLog(#"Cannot update while updating is in process...");
} else {
// run updates before getting information
[self getResponse:#"http://url/path/to/file?function=myvalue"];
[self setBottomBarToUpdating:#"Processing Please Wait..."];
dispatch_queue_t queue = dispatch_queue_create("updateQueue", DISPATCH_QUEUE_CONCURRENT);
UpdatingFlag = TRUE;
if(responseSuccess)
{
dispatch_async(dispatch_get_main_queue(),^ {
[self setBottomBarToUpdating:#"Updating..."];
[self updateFromXMLFile:#"https://url/path/to/file.xml"];
});
}
UpdatingFlag = FALSE;
dispatch_barrier_async(queue,^ {
dispatch_async(dispatch_get_main_queue(), ^{
[self setBottomBarToUpdated];
});
});
}
GetReponse Method
- (void) getResponse:(NSString *)url
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:45.0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
if (connection) {NSLog(#"Connecting...");
} else {NSLog(#"Didn't Connect Error...");}
}
Delegate Methods
#pragma mark NSURLConnection methods
- (void)connection:(NSURLConnection *)conn didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(#"Did Receive Challenge");
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential = [NSURLCredential credentialWithUser:#"user" password:#"pass" persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(#"Invalid Username and Password");
UIAlertView * userNameAlert = [[UIAlertView alloc]initWithTitle:#"Error"
message:#"ErrorMsg"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil];
[userNameAlert show];
}
}
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data {
NSLog(#"Received Data Packet...");
response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"Error, %#", error);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn {
NSLog(#"Finished Loading");
if([response rangeOfString:#"Complete"].location == NSNotFound) {
// success
responseSuccess = FALSE;
} else {
// failed
responseSuccess = TRUE;
}
}
- (BOOL)connection:(NSURLConnection *)conn canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return YES;
}
Any code you want to run after the you get the update from your server needs to be moved to (or called from) the connectionDidFinishLoading: method. So, you can get rid of the flags, and only have the getResponse call in your main code.
We must support some old code that runs using ASIHTTPRequest, but we want the object mapping and core data support provided by RestKit. Does anyone know of any way of "gluing" these two together?
I picture using ASIHTTPRequest for the requests and someone manually forwarding the payload over to RestKit.
Ok, so this wasn't too hard after all. Here is a class I wrote just for this (no disclaimers, it works for us and may be useful for someone else). You can use this as a direct replacement to the standard RKObjectLoader class.
.h file
#import <RestKit/RestKit.h>
#import "ASIFormDataRequest.h"
#interface ASIHTTPObjectLoader : ASIFormDataRequest <RKObjectMapperDelegate> {
RKObjectManager* _objectManager;
RKObjectMapping* _objectMapping;
RKObjectMappingResult* _result;
RKObjectMapping* _serializationMapping;
NSString* _serializationMIMEType;
NSObject* _sourceObject;
NSObject* _targetObject;
}
#property (nonatomic, retain) RKObjectMapping* objectMapping;
#property (nonatomic, readonly) RKObjectManager* objectManager;
#property (nonatomic, readonly) RKObjectMappingResult* result;
#property (nonatomic, retain) RKObjectMapping* serializationMapping;
#property (nonatomic, retain) NSString* serializationMIMEType;
#property (nonatomic, retain) NSObject* sourceObject;
#property (nonatomic, retain) NSObject* targetObject;
- (void) setDelegate:(id<RKObjectLoaderDelegate>)delegate;
+ (id)loaderWithResourcePath:(NSString*)resourcePath objectManager: (RKObjectManager*)objectManager delegate:(id<RKObjectLoaderDelegate>)delegate;
- (id)initWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id<RKObjectLoaderDelegate>)delegate;
- (void)handleResponseError;
#end
.m file
#import "ASIHTTPObjectLoader.h"
#interface ASIFormDataRequest (here)
- (void) reportFailure;
- (void) reportFinished;
#end
#implementation ASIHTTPObjectLoader
#synthesize objectManager = _objectManager;
#synthesize targetObject = _targetObject, objectMapping = _objectMapping;
#synthesize result = _result;
#synthesize serializationMapping = _serializationMapping;
#synthesize serializationMIMEType = _serializationMIMEType;
#synthesize sourceObject = _sourceObject;
- (void) setDelegate:(id<RKObjectLoaderDelegate>)_delegate {
[super setDelegate: _delegate];
}
+ (id)loaderWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id<RKObjectLoaderDelegate>)_delegate {
return [[[self alloc] initWithResourcePath:resourcePath objectManager:objectManager delegate:_delegate] autorelease];
}
- (id)initWithResourcePath:(NSString*)resourcePath objectManager:(RKObjectManager*)objectManager delegate:(id<RKObjectLoaderDelegate>)_delegate {
self = [super initWithURL: [objectManager.client URLForResourcePath: resourcePath]];
if ( self ) {
self.delegate = _delegate;
_objectManager = objectManager;
}
return self;
}
- (void)dealloc {
// Weak reference
_objectManager = nil;
[_sourceObject release];
_sourceObject = nil;
[_targetObject release];
_targetObject = nil;
[_objectMapping release];
_objectMapping = nil;
[_result release];
_result = nil;
[_serializationMIMEType release];
[_serializationMapping release];
[super dealloc];
}
- (void) reset {
[_result release];
_result = nil;
}
- (void)finalizeLoad:(BOOL)successful error:(NSError*)_error {
//_isLoading = NO;
if (successful) {
//_isLoaded = YES;
if ([self.delegate respondsToSelector:#selector(objectLoaderDidFinishLoading:)]) {
[self.delegate performSelectorOnMainThread:#selector(objectLoaderDidFinishLoading:)
withObject:self waitUntilDone:YES];
}
[super reportFinished];
/*
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:_response
forKey:RKRequestDidLoadResponseNotificationUserInfoResponseKey];
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidLoadResponseNotification
object:self
userInfo:userInfo];
*/
} else {
NSDictionary* _userInfo = [NSDictionary dictionaryWithObject:(_error ? _error : (NSError*)[NSNull null])
forKey:RKRequestDidFailWithErrorNotificationUserInfoErrorKey];
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidFailWithErrorNotification
object:self
userInfo:_userInfo];
}
}
// Invoked on the main thread. Inform the delegate.
- (void)informDelegateOfObjectLoadWithResultDictionary:(NSDictionary*)resultDictionary {
NSAssert([NSThread isMainThread], #"RKObjectLoaderDelegate callbacks must occur on the main thread");
RKObjectMappingResult* result = [RKObjectMappingResult mappingResultWithDictionary:resultDictionary];
if ([self.delegate respondsToSelector:#selector(objectLoader:didLoadObjectDictionary:)]) {
[self.delegate objectLoader: (RKObjectLoader*)self didLoadObjectDictionary:[result asDictionary]];
}
if ([self.delegate respondsToSelector:#selector(objectLoader:didLoadObjects:)]) {
[self.delegate objectLoader: (RKObjectLoader*)self didLoadObjects:[result asCollection]];
}
if ([self.delegate respondsToSelector:#selector(objectLoader:didLoadObject:)]) {
[self.delegate objectLoader: (RKObjectLoader*)self didLoadObject:[result asObject]];
}
[self finalizeLoad:YES error:nil];
}
#pragma mark - Subclass Hooks
/**
Overloaded by ASIHTTPManagedObjectLoader to serialize/deserialize managed objects
at thread boundaries.
#protected
*/
- (void)processMappingResult:(RKObjectMappingResult*)result {
NSAssert(isSynchronous || ![NSThread isMainThread], #"Mapping result processing should occur on a background thread");
[self performSelectorOnMainThread:#selector(informDelegateOfObjectLoadWithResultDictionary:) withObject:[result asDictionary] waitUntilDone:YES];
}
#pragma mark - Response Object Mapping
- (RKObjectMappingResult*)mapResponseWithMappingProvider:(RKObjectMappingProvider*)mappingProvider toObject:(id)targetObject error:(NSError**)_error {
NSString* MIMEType = [[self responseHeaders] objectForKey: #"Content-Type"];
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType: MIMEType];
NSAssert1(parser, #"Cannot perform object load without a parser for MIME Type '%#'", MIMEType);
// Check that there is actually content in the response body for mapping. It is possible to get back a 200 response
// with the appropriate MIME Type with no content (such as for a successful PUT or DELETE). Make sure we don't generate an error
// in these cases
id bodyAsString = [self responseString];
if (bodyAsString == nil || [[bodyAsString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
RKLogDebug(#"Mapping attempted on empty response body...");
if (self.targetObject) {
return [RKObjectMappingResult mappingResultWithDictionary:[NSDictionary dictionaryWithObject:self.targetObject forKey:#""]];
}
return [RKObjectMappingResult mappingResultWithDictionary:[NSDictionary dictionary]];
}
id parsedData = [parser objectFromString:bodyAsString error:_error];
if (parsedData == nil && _error) {
return nil;
}
// Allow the delegate to manipulate the data
if ([self.delegate respondsToSelector:#selector(objectLoader:willMapData:)]) {
parsedData = [[parsedData mutableCopy] autorelease];
[self.delegate objectLoader: (RKObjectLoader*)self willMapData:&parsedData];
}
RKObjectMapper* mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:mappingProvider];
mapper.targetObject = targetObject;
mapper.delegate = self;
RKObjectMappingResult* result = [mapper performMapping];
// Log any mapping errors
if (mapper.errorCount > 0) {
RKLogError(#"Encountered errors during mapping: %#", [[mapper.errors valueForKey:#"localizedDescription"] componentsJoinedByString:#", "]);
}
// The object mapper will return a nil result if mapping failed
if (nil == result) {
// TODO: Construct a composite error that wraps up all the other errors. Should probably make it performMapping:&error when we have this?
if (_error) *_error = [mapper.errors lastObject];
return nil;
}
return result;
}
- (RKObjectMappingResult*)performMapping:(NSError**)_error {
NSAssert( isSynchronous || ![NSThread isMainThread], #"Mapping should occur on a background thread");
RKObjectMappingProvider* mappingProvider;
if (self.objectMapping) {
NSString* rootKeyPath = self.objectMapping.rootKeyPath ? self.objectMapping.rootKeyPath : #"";
RKLogDebug(#"Found directly configured object mapping, creating temporary mapping provider for keyPath %#", rootKeyPath);
mappingProvider = [[RKObjectMappingProvider new] autorelease];
[mappingProvider setMapping:self.objectMapping forKeyPath:rootKeyPath];
} else {
RKLogDebug(#"No object mapping provider, using mapping provider from parent object manager to perform KVC mapping");
mappingProvider = self.objectManager.mappingProvider;
}
return [self mapResponseWithMappingProvider:mappingProvider toObject:self.targetObject error:_error];
}
- (void)performMappingOnBackgroundThread {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSError* _error = nil;
_result = [[self performMapping:&_error] retain];
NSAssert(_result || _error, #"Expected performMapping to return a mapping result or an error.");
if (self.result) {
[self processMappingResult:self.result];
} else if (_error) {
[self failWithError: _error];
}
[pool drain];
}
- (BOOL)canParseMIMEType:(NSString*)MIMEType {
if ([[RKParserRegistry sharedRegistry] parserForMIMEType: MIMEType]) {
return YES;
}
RKLogWarning(#"Unable to find parser for MIME Type '%#'", MIMEType);
return NO;
}
- (BOOL)isResponseMappable {
if ([self responseStatusCode] == 503) {
[[NSNotificationCenter defaultCenter] postNotificationName:RKServiceDidBecomeUnavailableNotification object:self];
}
NSString* MIMEType = [[self responseHeaders] objectForKey: #"Content-Type"];
if ( error ) {
[self.delegate objectLoader: (RKObjectLoader*)self didFailWithError: error];
[self finalizeLoad:NO error: error];
return NO;
} else if ([self responseStatusCode] == 204) {
// The No Content (204) response will never have a message body or a MIME Type. Invoke the delegate with self
[self informDelegateOfObjectLoadWithResultDictionary:[NSDictionary dictionaryWithObject:self forKey:#""]];
return NO;
} else if (NO == [self canParseMIMEType: MIMEType]) {
// We can't parse the response, it's unmappable regardless of the status code
RKLogWarning(#"Encountered unexpected response with status code: %ld (MIME Type: %#)", (long) [self responseStatusCode], MIMEType);
NSError* _error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKObjectLoaderUnexpectedResponseError userInfo:nil];
if ([self.delegate respondsToSelector:#selector(objectLoaderDidLoadUnexpectedResponse:)]) {
[self.delegate objectLoaderDidLoadUnexpectedResponse: (RKObjectLoader*)self];
} else {
[self.delegate objectLoader: (RKObjectLoader*)self didFailWithError: _error];
}
// NOTE: We skip didFailLoadWithError: here so that we don't send the delegate
// conflicting messages around unexpected response and failure with error
[self finalizeLoad:NO error:_error];
return NO;
} else if (([self responseStatusCode] >= 400 && [self responseStatusCode] < 500) ||
([self responseStatusCode] >= 500 && [self responseStatusCode] < 600) ) {
// This is an error and we can map the MIME Type of the response
[self handleResponseError];
return NO;
}
return YES;
}
- (void)handleResponseError {
// Since we are mapping what we know to be an error response, we don't want to map the result back onto our
// target object
NSError* _error = nil;
RKObjectMappingResult* result = [self mapResponseWithMappingProvider:self.objectManager.mappingProvider toObject:nil error:&_error];
if (result) {
_error = [result asError];
} else {
RKLogError(#"Encountered an error while attempting to map server side errors from payload: %#", [_error localizedDescription]);
}
[self.delegate objectLoader: (RKObjectLoader*)self didFailWithError:_error];
[self finalizeLoad:NO error:_error];
}
#pragma mark - RKRequest & RKRequestDelegate methods
- (void) reportFailure {
[self.delegate objectLoader: (RKObjectLoader*)self didFailWithError:error];
[super reportFailure];
}
- (void)reportFinished {
NSAssert([NSThread isMainThread], #"RKObjectLoaderDelegate callbacks must occur on the main thread");
if ([self isResponseMappable]) {
// Determine if we are synchronous here or not.
if (isSynchronous) {
NSError* _error = nil;
_result = [[self performMapping:&_error] retain];
if (self.result) {
[self processMappingResult:self.result];
} else {
[self performSelectorInBackground:#selector(failWithError:) withObject:_error];
}
[super reportFinished];
} else {
[self performSelectorInBackground:#selector(performMappingOnBackgroundThread) withObject:nil];
}
}
}
I do the following in my unit test code to make sure my object mappings are working
NSDictionary *headers = [NSDictionary dictionaryWithObjectsAndKeys:#"application/json", #"X-RESTKIT-CACHED-MIME-TYPE",
#"200", #"X-RESTKIT-CACHED-RESPONSE-CODE",
#"application/json; charset=utf-8", #"Content-Type",
nil];
NSURL *url = [[NSURL alloc] initWithString:#""]; //need a url to create a dummy RKRequest
RKRequest *request = [RKRequest requestWithURL:url];
[url release];
//Create a dummy response with the data payload
RKResponse *response = [[[RKResponse alloc] initWithRequest:request
body:myData //myData is NSData loaded from my file on disk in this case
headers:headers] autorelease];
RKURL *rkURL = [[RKURL alloc] initWithString:#"https://api.twitter.com"];
RKManagedObjectLoader *loader = [[RKManagedObjectLoader alloc] initWithURL:rkURL
mappingProvider:self.objectManager.mappingProvider
objectStore:self.objectManager.objectStore];
loader.delegate = self;
loader.objectMapping = self.objectMapping; //I pass the object mapping to use here.
[loader didFinishLoad:response]; //Given a response and request, Restkit will parse the response and call the usual delegates
You might be able to do somthing similar as well to grab the response data from ASIHTTPRequest and pass it on to RestKit
I want to create a to-do list with SQLite, and I have been following this tutorial: http://klanguedoc.hubpages.com/hub/IOS-5-How-To-Display-SQLite-Data-in-a-UITableView
but it's not working! The simulator runs, and the app opens, but the table is blank. Am I doing something wrong? I am using xcode 4.2 for snow leopard.
In the .sqlite file I have a string text, integer priority, and boolean complete. However, I've just implemented "text" to make things simpler.
Here's my code:
// Title.h
#import <Foundation/Foundation.h>
#interface Title : NSObject {
NSString *text;
}
#property(nonatomic,copy) NSString *text;
#end
//TitleVC.h
#import <UIKit/UIKit.h>
#import <sqlite3.h>
#interface TitleVC : UITableViewController{
NSMutableArray *thelist;
sqlite3 *db;
}
#property (nonatomic,retain) NSMutableArray *thelist;
-(NSMutableArray *) toDo;
#end
//TitleVC.m
#import "TitleVC.h"
#import "Title.h"
#import <sqlite3.h>
#implementation TitleVC
#synthesize thelist;
- (void)viewDidLoad
{
[self toDo];
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.thelist count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
int rowCount = indexPath.row;
Title *title = [self.thelist objectAtIndex:rowCount];
cell.textLabel.text = title.text;
return cell;
}
-(NSMutableArray *) toDo{
thelist = [[NSMutableArray alloc] initWithCapacity:10];
#try{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:#"todo.sqlite"];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success)
{
NSLog(#"Cannot locate database file '%#'.",dbPath);
}
if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
{
NSLog(#"An error has occured: %#",sqlite3_errmsg(db));
}
const char *sql = "SELECT * FROM todo";
sqlite3_stmt *sqlStatement;
if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
{
NSLog(#"Problem with prepare statement: %#", sqlite3_errmsg(db));
}else{
Title *title = [[Title alloc] init];
while (sqlite3_step(sqlStatement)==SQLITE_ROW){
title.text = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)];
[thelist addObject:title];
}
}
}
#catch (NSException *exception) {
NSLog(#"Problem with prepare statement: %#", sqlite3_errmsg(db));
}
#finally {
return thelist;
}
}
If you are using a standard UITableView, is tableView:numberOfRowsInSection: returning an appropriate value? What is tableView:cellForRowAtIndexPath: returning? I would put a break point in both locations and check to make that the methods are even being called.
Finally, if you are using a .xib file, is there a connection to the UITableView?