Core data - Check for null - iOS - ios

On entering a new data into my core data for my given entity, how do I check if the entry for a particular attribute is null?
I have three attribute
name, mail and mailedCustomer.
I add data as follows:
SalesPerson *data = (SalesPerson *)[NSEntityDescription insertNewObjectForEntityForName:#"SalesPerson" inManagedObjectContext:self.managedObjectContext];
[data setName:name];
[data setEmail:userEmail];
NSLog(#" mailed personel%#",data.mailedCustomer);
if([data.mailedCustomer != nil){
NSLog(#"inside condition");
[data setMailedCustomer:#"//"];
}
This doesn't work for me. Im trying to append some strings. So when I enter for the first time I need that attribute to be #"//" then append on further calls.
NSLog(#" mailed personnel %#",data.mailedCustomer);
The above NSLog gives me:
mailed personnel (null)

If I get what you want, your if statement is incorrect. You're now checking if it's NOT nil (meaning it has some value), and then you're resetting it to //. If you want it to be // and then append values, you have to check if it IS nil and then set it to //:
if (!data.mailedCustomer) {
NSLog(#"inside condition");
[data setMailedCustomer:#"//"];
}

#interface NSObject (PE)
- (BOOL) isNull:(NSObject*) object;
- (BOOL) isNotNull:(NSObject*) object;
#end
#implementation NSObject (PE)
- (BOOL) isNull:(NSObject*) object {
if (!object)
return YES;
else if (object == [NSNull null])
return YES;
else if ([object isKindOfClass: [NSString class]]) {
return ([((NSString*)object) isEqualToString:#""]
|| [((NSString*)object) isEqualToString:#"null"]
|| [((NSString*)object) isEqualToString:#"<null>"]);
}
return NO;
}
- (BOOL) isNotNull:(NSObject*) object {
return ![self isNull:object];
}
#end
if([self isNotNull:some object])
{
not null
}
else
{
null
}

Related

CloudKit integration requires that the value transformers for transformable attributes are available via +[NSValueTransformer valueTransformerForName:

I'm using CoreData+CloudKit to store data, currently there are two Entities,AEntity and BEntity:
In AEntity, there is an attribute: content, used to store NSAttributedString, its Type is "Transformable", I set its "Transformer" to "AttributedStringValueTransformer" in the right menu of Xcode:
#implementation AttributedStringValueTransformer
+ (Class)transformedValueClass {
return [NSAttributedString class];
}
+ (BOOL)allowsReverseTransformation {
return YES;
}
- (NSData *)transformedValue:(NSAttributedString *)value {
if (!value) {
return nil;
}
if ([value isKindOfClass:[NSData class]]) {
return (NSData *)value;
}
NSData *stringAsData = [NSKeyedArchiver archivedDataWithRootObject:value];
return stringAsData;
}
- (NSAttributedString *)reverseTransformedValue:(NSData *)value {
NSAttributedString *attributedString = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return attributedString;
}
#end
In BEntity, there is an Attribute: images, which is used to store image arrays (NSArray), and its Type is also "Transformable". I set its "Transformer" to "ArrayValueTransformer" in the right menu of Xcode:
#implementation ArrayValueTransformer
+ (Class)transformedValueClass {
return [NSArray class];
}
+ (BOOL)allowsReverseTransformation {
return YES;
}
- (NSData *)transformedValue:(NSAttributedString *)value {
if (!value) {
return nil;
}
if ([value isKindOfClass:[NSData class]]) {
return (NSData *)value;
}
return [NSKeyedArchiver archivedDataWithRootObject:value];;
}
- (NSAttributedString *)reverseTransformedValue:(NSData *)value {
return [NSKeyedUnarchiver unarchiveObjectWithData:value];
}
#end
When calling the loadPersistentStoresWithCompletionHandler: method:
+ (instancetype)containerWithName:(NSString *)name {
NSPersistentCloudKitContainer *persistentContainer = [[NSPersistentCloudKitContainer alloc] initWithName:name];
persistentContainer.viewContext.automaticallyMergesChangesFromParent = YES;
NSPersistentStoreDescription *description = [persistentContainer.persistentStoreDescriptions firstObject];
[description setOption:#(YES) forKey:NSPersistentHistoryTrackingKey];
[description setOption:#(YES) forKey:NSPersistentStoreRemoteChangeNotificationPostOptionKey];
description.shouldInferMappingModelAutomatically = YES;
description.shouldMigrateStoreAutomatically = YES;
persistentContainer.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
[persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
if (error != nil) {
NSLog(#"Unresolved error %#, %#", error, error.userInfo);
// abort();
}
}];
return persistentContainer;
}
The error information in the callback of loadPersistentStoresWithCompletionHandler is:
Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error
occurred." UserInfo={NSLocalizedFailureReason=CloudKit integration
requires that the value transformers for transformable attributes are
available via +[NSValueTransformer valueTransformerForName:], return
instances of NSData, and allow reverse transformation: AEntity:
content - Claims to return instances of NSAttributedString BEntity:
images - Claims to return instances of NSArray}
What is the reason for this? And how should this problem be solved?

how to check if array is null or empty in ios sdk?

I want to check if my Bond is empty or null and NULL value.
{
Bonds =(
{
DOB = "12/09/1988";
about = "";
}
);
User = {
city = CA;
email = "karmhadadmtl#gmail.com";
};
success = True;
}
Second time this type get data how to check Bond key
{
Bonds = Null;
User = {
city = CA;
email = "developer.i12#gmail.com";
};
success = True;
}
You just check for nil
if(data[#"Bonds"]==nil){
NSLog(#"it is nil");
}
or
if ([data[#"Bonds"] isKindOfClass:[NSNull class]]) {
NSLog(#"it is null");
}
if ([data[#"Bonds"] isKindOfClass:[NSNull class]] || data[#"Bonds"] == nil || [data[#"Bonds"] isEqualToString:#""]) {
}
[NSNull null] always returns a same object so this should work fine.
if (dictionary[#"Bonds"] != [NSNull null]) {
// requried data is present, now check if it is nil or empty.
}
check: if (![dataArray isKindOfClass:[NSNull class]]) &&
check if it having elements [dataArray firstObject] - to check array having one or more elements.
The best possible way should be:
if (!data[#"Bonds"] || ![data[#"Bonds"] count]){
NSLog(#"Data Found");
}else{
NSLog(#"Data Not Found");
}

Find part of a string and then search for another part of he string

I want to be able to search for certain characters in a NSString and if the app has found it, I want it to look for another part of the string. The problem is that the code that I have so far:
- (IBAction)searchButtonTapped:(id)sender {
NSString *data = [NSString stringWithFormat:#"http://www.example.com/example.pdf"];
if ([data rangeOfString:#"http://"].location != NSNotFound) {
if ([data rangeOfString:#".pdf"].location != NSNotFound) {
NSLog(#"Found .pdf");
} else {
NSLog(#"Did not find .pdf");
}
}
}
... doesn't work; it goes straight to the else statement instead of the if statement. How do I solve this? Thanks in advance.
For some silly reason, it works when I tell it to search a different string.
NSString *data = [NSString stringWithFormat:#"http://www.example.com/example.pdf"];
if ([data rangeOfString:#"http://"].location != NSNotFound) {
NSString *dataToSearchRangeOfString = data;
if ([dataToSearchRangeOfString rangeOfString:#".pdf"].location != NSNotFound) {
NSLog(#"Found .pdf");
} else {
NSLog(#"Did not find .pdf");
}
}
If anyone does know how to solve this issue without needing to do this, I will gladly mark down your answer as correct.
Your current code should work,,
but you can Try this alternative;
- (BOOL)isPdfUrl:(NSString*)urls {
NSArray *elements = #[#"http", #"."];
for (NSString *element in elements) {
if ([urls rangeOfString:element].location == NSNotFound) {
return NO;
}
}
NSArray *possibleFiles = #[#"pdf"];
for (NSString *file in possibleFiles) {
if ([urls rangeOfString:file].location != NSNotFound) {
return YES;
}
}
return NO;
}
May be, there are some cyrillic symbols? For example you can check if 'p' is not a russian 'р'.

ios compare boolean from json

I got a boolean value from a json object using dictionary. at console, I can see 0 or 1.
But my comparision always return true.
BOOL *result =[dictionary valueForKey:#"result"];
if (result == YES) {
[parser release];
}
else {
errorLbl.text = #"Login failed";
}
have you tried adding a boolValue at the end of [dictionary valueForKey:#"result"]boolValue];
You need to convert the value from the dictionary. You can't translate it directly to a BOOL * (BOOL pointer).
Suppose you get a NSString* from your dictionary, you can do:
NSString *result = [dictionary valueForKey:#"result"];
if ([result boolValue]) {
[parser release];
} else {
errorLbl.text = #"Login failed";
}
Assuming you can use boolValue message with your protocol.
Try with the below code, I got
BOOL success = [[jsonDict objectForKey:#"success"] boolValue];
if (success == YES){ //Do some stuff } else{ //Do some stuff }

Case Insensitive Search in NSMutableDictionary

HI, I have a NSMutableDicitionary contains both lowercase and uppercase keys. So currently i don't know how to find the key in the dictionary irrespective key using objective c.
Categories to the rescue.
Ok, so it's an old post...
#interface NSDictionary (caseINsensitive)
-(id) objectForCaseInsensitiveKey:(id)aKey;
#end
#interface NSMutableDictionary (caseINsensitive)
-(void) setObject:(id) obj forCaseInsensitiveKey:(id)aKey ;
#end
#implementation NSDictionary (caseINsensitive)
-(id) objectForCaseInsensitiveKey:(id)aKey {
for (NSString *key in self.allKeys) {
if ([key compare:aKey options:NSCaseInsensitiveSearch] == NSOrderedSame) {
return [self objectForKey:key];
}
}
return nil;
}
#end
#implementation NSMutableDictionary (caseINsensitive)
-(void) setObject:(id) obj forCaseInsensitiveKey:(id)aKey {
for (NSString *key in self.allKeys) {
if ([key compare:aKey options:NSCaseInsensitiveSearch] == NSOrderedSame) {
[self setObject:obj forKey:key];
return;
}
}
[self setObject:obj forKey:aKey];
}
#end
enjoy.
Do you have control over the creation of the keys? If you do, I'd just force the keys to either lower or upper case when you're creating them. This way when you need to look up something, you don't have to worry about mixed case keys.
You can do this to get the object as an alternative to subclassing.
__block id object;
[dictionary enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
UsingBlock:^(id key, id obj, BOOL *stop){
if ( [key isKindOfClass:[NSString class]] ) {
if ( [(NSString*)key caseInsensitiveCompare:aString] == NSOrderedSame ) {
object = obj; // retain if wish to.
*stop = YES;
}
}
}];
You can use a #define shorthand if you find yourself doing this a lot in your code.
Don't think there's any easy way. Your best option might be to create a subclass of NSMutableDictionary, and override the objectForKey and setObject:ForKey methoods. Then in your overridden methods ensure that all keys are converted to lowercase (or uppercase), before passing them up to the superclass methdods.
Something along the lines of the following should work:
#Interface CaseInsensitveMutableDictionary : MutableDictionary {}
#end
#implementation CaseInsensitveMutableDictionary
- (void) setObject: (id) anObject forKey: (id) aKey {
[super setObject:anObject forKey:[skey lowercaseString]];
}
- (id) objectForKey: (id) aKey {
return [super objectForKey: [aKey lowercaseString]];
}
#end

Resources