List of NSException derived classes or exception names? - ios

I've been through Introduction to Exception Programming Topics for Cocoa. Under Throwing Exceptions, there is one exception name shown: FileNotFoundException:
NSException *e = [NSException
exceptionWithName:#"FileNotFoundException"
reason:#"File Not Found on System"
userInfo:nil];
#throw e;
However, the Predefined Exceptions page lists about 10 exceptions and FileNotFoundException is not listed.
Where can I find a list of common or expected exceptions and names?

That's weird, these are the only constants defined in NSExcpetion.h that I see:
FOUNDATION_EXPORT NSString * const NSGenericException;
FOUNDATION_EXPORT NSString * const NSRangeException;
FOUNDATION_EXPORT NSString * const NSInvalidArgumentException;
FOUNDATION_EXPORT NSString * const NSInternalInconsistencyException;
FOUNDATION_EXPORT NSString * const NSMallocException;
FOUNDATION_EXPORT NSString * const NSObjectInaccessibleException;
FOUNDATION_EXPORT NSString * const NSObjectNotAvailableException;
FOUNDATION_EXPORT NSString * const NSDestinationInvalidException;
FOUNDATION_EXPORT NSString * const NSPortTimeoutException;
FOUNDATION_EXPORT NSString * const NSInvalidSendPortException;
FOUNDATION_EXPORT NSString * const NSInvalidReceivePortException;
FOUNDATION_EXPORT NSString * const NSPortSendException;
FOUNDATION_EXPORT NSString * const NSPortReceiveException;
FOUNDATION_EXPORT NSString * const NSOldStyleException;

The exception FileNotFoundException shown in that particular example is not a predefined exception. All predefined exceptions begin with prefix NS, like NSRangeException etc. Hence you cannot see it listed under the predefined list of exceptions.
From Apple docs
Note that all predefined exceptions begin with the prefix "NS", so you should avoid using the same prefix when creating new exception names.
FileNotFoundException is custom exception, which needs to be raised and handled by the developer for custom error conditions. It is recommended that all custom exception should avoid using the prefix NS.
As mentioned by pfrank in his answer, list of predefined exceptions can be found here
extern NSString *NSGenericException;
extern NSString *NSRangeException;
extern NSString *NSInvalidArgumentException;
extern NSString *NSInternalInconsistencyException;
extern NSString *NSMallocException;
extern NSString *NSObjectInaccessibleException;
extern NSString *NSObjectNotAvailableException;
extern NSString *NSDestinationInvalidException;
extern NSString *NSPortTimeoutException;
extern NSString *NSInvalidSendPortException;
extern NSString *NSInvalidReceivePortException;
extern NSString *NSPortSendException;
extern NSString *NSPortReceiveException;
extern NSString *NSOldStyleException;
Hope that helps!

Related

SHA1 hash not accepted by API

I'm developing an app that uses a barcode to pull data from an API.
For each call I need to generate a hash value as a signature. Which is a combination of my API ID and the barcode.
I've got an issue where my hashed value is the same each time, therefore my calls are failing.
The functions to create the hash are in objective-C and I have a bridge so I can call it in SwiftUI.
NSString+SHA1.m
#import "NSString+SHA1.h"
#import <CommonCrypto/CommonHMAC.h>
#implementation NSString (SHA1)
- (NSString *)hashedValue:(NSString *)key
{
const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
const char *cData = [self cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hash = [HMAC base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
//Used to be [HMAC base64Encoding], but is now depreciated
return hash;
}
#end
As base64Encoding is depreciated, I tried to use base64EncodedStringWithOptions instead. This may be done incorrectly and could be the cause of why my hash value is the same each time.
This is how I call it in SwiftUI:
let hashedValue = scannedCode.barcode.hashedValue("(API ID)")
scannedCode is an observable object that stores the scanned barcode under "barcode" as a String.
In the bridging header:
#import "NSString+SHA1.h"
#import "NSString+SHA1.m"
NSString+SHA1.h
#import <Foundation/Foundation.h>
#interface NSString (SHA1)
- (NSString *)hashedValue:(NSString *)key;
#end
EDIT:
I fixed the problem of the hash value being the same, but the API still isn't accepting my signature. So it's to do with the calculation being wrong.

Get Global Const to autocomplete in Xcode

I was under the assumption that the entire point of constants was to avoid typos and make life easier....but thats not so true if I cant get const to auto suggest in classes they are available in. Am I doing something wrong?
#import <Foundation/Foundation.h>
#interface NSDefaultsConstants : NSObject
FOUNDATION_EXPORT NSString* const user_full_name;
FOUNDATION_EXPORT NSString* const user_first_name;
FOUNDATION_EXPORT NSString* const user_last_name;
FOUNDATION_EXPORT NSString* const user_cover_photo;
FOUNDATION_EXPORT NSString* const user_default_photo;
FOUNDATION_EXPORT NSString* const user_udid;
FOUNDATION_EXPORT NSString* const session_draft_status_text;
FOUNDATION_EXPORT NSString* const session_draft_image_url;
#end
#import "NSDefaultsConstants.h"
#implementation NSDefaultsConstants
#end
NSString* const user_full_name = #"user_fullname";
NSString* const user_first_name = #"user_first_name";
NSString* const user_last_name = #"user_last_name";
NSString* const user_cover_photo = #"user_cover_photo";
NSString* const user_default_photo = #"user_default_photo";
NSString* const user_udid = #"user_udid";
NSString* const session_draft_status_text = #"session_draft_status_text";
NSString* const session_draft_image_url = #"session_draft_image_url";

ABPeoplePickerNavigationController predicate for enabling selection of the contact with predicateForEnablingPerson

I have an ABPeoplePickerNavigationController as below
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
I need to disable some of the contacts being selected from the ABPeoplePickerNavigationController's list view.
While browsing, got some idea like this
// Predicate to enable only the contacts having a mail id atleast.
picker.predicateForEnablingPerson = [NSPredicate predicateWithFormat:#"emailAddresses.#count > 0"];
So I implemented a predicate like below to exclude the selection of contact with the first name I have.
NSString *firstName = #"Kate";
// Predicate to disable selection of the contacts with the first name given.
picker.predicateForEnablingPerson = [NSPredicate predicateWithFormat:#"firstName != %#",firstName];
Unfortunately its not working.
I found the list of the constants that you can use in the predicate in ABPeoplePickerNavigationController.h
// Constants to use in predicates:
// A LabeledValue has a 'label' property and a 'value' property.
// A PhoneNumber has a 'stringValue' property, a 'countryCode' property, a 'formattedStringValue' property and a 'normalizedStringValue' property
// A InstantMessageAddress has a 'username' property and a 'service' property
// A SocialProfile has a 'username' property and a 'service' property
// A PostalAddress has a 'street' property, a 'subLocality' property, a 'city' property, a 'subAdministrativeArea' property, a 'state' property, a 'postalCode' property, a 'country' property and a 'ISOCountryCode' property
//
extern NSString * const ABPersonNamePrefixProperty NS_AVAILABLE_IOS(8_0); // "namePrefix" NSString
extern NSString * const ABPersonGivenNameProperty NS_AVAILABLE_IOS(8_0); // "givenName" NSString
extern NSString * const ABPersonMiddleNameProperty NS_AVAILABLE_IOS(8_0); // "middleName" NSString
extern NSString * const ABPersonFamilyNameProperty NS_AVAILABLE_IOS(8_0); // "familyName" NSString
extern NSString * const ABPersonNameSuffixProperty NS_AVAILABLE_IOS(8_0); // "nameSuffix" NSString
extern NSString * const ABPersonPreviousFamilyNameProperty NS_AVAILABLE_IOS(8_0); // "previousFamilyName" NSString
extern NSString * const ABPersonNicknameProperty NS_AVAILABLE_IOS(8_0); // "nickname" NSString
extern NSString * const ABPersonPhoneticGivenNameProperty NS_AVAILABLE_IOS(8_0); // "phoneticGivenName" NSString
extern NSString * const ABPersonPhoneticMiddleNameProperty NS_AVAILABLE_IOS(8_0); // "phoneticMiddleName" NSString
extern NSString * const ABPersonPhoneticFamilyNameProperty NS_AVAILABLE_IOS(8_0); // "phoneticFamilyName" NSString
extern NSString * const ABPersonOrganizationNameProperty NS_AVAILABLE_IOS(8_0); // "organizationName" NSString
extern NSString * const ABPersonDepartmentNameProperty NS_AVAILABLE_IOS(8_0); // "departmentName" NSString
extern NSString * const ABPersonJobTitleProperty NS_AVAILABLE_IOS(8_0); // "jobTitle" NSString
extern NSString * const ABPersonBirthdayProperty NS_AVAILABLE_IOS(8_0); // "birthday" NSDateComponents
extern NSString * const ABPersonNoteProperty NS_AVAILABLE_IOS(8_0); // "note" NSString
extern NSString * const ABPersonPhoneNumbersProperty NS_AVAILABLE_IOS(8_0); // "phoneNumbers" array of LabeledValue with PhoneNumber values
extern NSString * const ABPersonEmailAddressesProperty NS_AVAILABLE_IOS(8_0); // "emailAddresses" array of LabeledValue with NSString values
extern NSString * const ABPersonUrlAddressesProperty NS_AVAILABLE_IOS(8_0); // "urlAddresses" array of LabeledValue with NSString values
extern NSString * const ABPersonDatesProperty NS_AVAILABLE_IOS(8_0); // "dates" array of LabeledValue with NSDateComponents values
extern NSString * const ABPersonInstantMessageAddressesProperty NS_AVAILABLE_IOS(8_0); // "instantMessageAddresses" array of LabeledValue with InstantMessageAddress values
extern NSString * const ABPersonRelatedNamesProperty NS_AVAILABLE_IOS(8_0); // "relatedNames" array of LabeledValue with NSString values
extern NSString * const ABPersonSocialProfilesProperty NS_AVAILABLE_IOS(8_0); // "socialProfiles" array of LabeledValue with SocialProfile values
extern NSString * const ABPersonPostalAddressesProperty NS_AVAILABLE_IOS(8_0); // "postalAddresses" array of LabeledValue with PostalAddress values

ABPeoplePickerNavigationController predicateForEnablingPerson - What is the Predicate Format for Street Address?

With iOS 8 ABPeoplePickerNavigationController has:
// Optionally determines if a person can be selected or not.
// If not set, all persons will be selectable.
//
#property(nonatomic,copy) NSPredicate *predicateForEnablingPerson NS_AVAILABLE_IOS(8_0);
I'd like to disable the address book contacts that don't have a street address.
I've seen (and tested) the following, which only enables contacts with at least one email address:
if ([peoplePickerNavigationController respondsToSelector:#selector(predicateForEnablingPerson)]) {
peoplePickerNavigationController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:#"emailAddresses.#count > 0"];
}
What do I replace the string "emailAddresses.#count > 0" with in order to only enable contacts with at least one street address?
You can use:
controller.predicateForEnablingPerson = [NSPredicate predicateWithFormat:#"%K.#count > 0", ABPersonPostalAddressesProperty];
The header gives a list of the acceptable constants to be used in predicates:
// Constants to use in predicates:
// A LabeledValue has a 'label' property and a 'value' property.
// A PhoneNumber has a 'stringValue' property, a 'countryCode' property, a 'formattedStringValue' property and a 'normalizedStringValue' property
// A InstantMessageAddress has a 'username' property and a 'service' property
// A SocialProfile has a 'username' property and a 'service' property
// A PostalAddress has a 'street' property, a 'subLocality' property, a 'city' property, a 'subAdministrativeArea' property, a 'state' property, a 'postalCode' property, a 'country' property and a 'ISOCountryCode' property
//
extern NSString * const ABPersonNamePrefixProperty NS_AVAILABLE_IOS(8_0); // "namePrefix" NSString
extern NSString * const ABPersonGivenNameProperty NS_AVAILABLE_IOS(8_0); // "givenName" NSString
extern NSString * const ABPersonMiddleNameProperty NS_AVAILABLE_IOS(8_0); // "middleName" NSString
extern NSString * const ABPersonFamilyNameProperty NS_AVAILABLE_IOS(8_0); // "familyName" NSString
extern NSString * const ABPersonNameSuffixProperty NS_AVAILABLE_IOS(8_0); // "nameSuffix" NSString
extern NSString * const ABPersonPreviousFamilyNameProperty NS_AVAILABLE_IOS(8_0); // "previousFamilyName" NSString
extern NSString * const ABPersonNicknameProperty NS_AVAILABLE_IOS(8_0); // "nickname" NSString
extern NSString * const ABPersonPhoneticGivenNameProperty NS_AVAILABLE_IOS(8_0); // "phoneticGivenName" NSString
extern NSString * const ABPersonPhoneticMiddleNameProperty NS_AVAILABLE_IOS(8_0); // "phoneticMiddleName" NSString
extern NSString * const ABPersonPhoneticFamilyNameProperty NS_AVAILABLE_IOS(8_0); // "phoneticFamilyName" NSString
extern NSString * const ABPersonOrganizationNameProperty NS_AVAILABLE_IOS(8_0); // "organizationName" NSString
extern NSString * const ABPersonDepartmentNameProperty NS_AVAILABLE_IOS(8_0); // "departmentName" NSString
extern NSString * const ABPersonJobTitleProperty NS_AVAILABLE_IOS(8_0); // "jobTitle" NSString
extern NSString * const ABPersonBirthdayProperty NS_AVAILABLE_IOS(8_0); // "birthday" NSDateComponents
extern NSString * const ABPersonNoteProperty NS_AVAILABLE_IOS(8_0); // "note" NSString
extern NSString * const ABPersonPhoneNumbersProperty NS_AVAILABLE_IOS(8_0); // "phoneNumbers" array of LabeledValue with PhoneNumber values
extern NSString * const ABPersonEmailAddressesProperty NS_AVAILABLE_IOS(8_0); // "emailAddresses" array of LabeledValue with NSString values
extern NSString * const ABPersonUrlAddressesProperty NS_AVAILABLE_IOS(8_0); // "urlAddresses" array of LabeledValue with NSString values
extern NSString * const ABPersonDatesProperty NS_AVAILABLE_IOS(8_0); // "dates" array of LabeledValue with NSDateComponents values
extern NSString * const ABPersonInstantMessageAddressesProperty NS_AVAILABLE_IOS(8_0); // "instantMessageAddresses" array of LabeledValue with InstantMessageAddress values
extern NSString * const ABPersonRelatedNamesProperty NS_AVAILABLE_IOS(8_0); // "relatedNames" array of LabeledValue with NSString values
extern NSString * const ABPersonSocialProfilesProperty NS_AVAILABLE_IOS(8_0); // "socialProfiles" array of LabeledValue with SocialProfile values
extern NSString * const ABPersonPostalAddressesProperty NS_AVAILABLE_IOS(8_0); // "postalAddresses" array of LabeledValue with PostalAddress values
If you look at the header, that's postalAddresses

NSLog disable from certain classes and DEBUG

Hello guys I have found this code that is used to create a different NSLog (without data and timestamps) that displays the class where the log was made and the line number.
I have read that is possible to disable the logging only for certain classes with NO_LOG but there was not explained how to use it exactly, I am quite new to obj-c and I appreciate an explanation on how to disable logging for certain classes and how to activate and deactivate the debugging. thanks
#define MAKESTRING(__VA_ARGS__) #__VA_ARGS__
#define TOSTRING(...) MAKESTRING(__VA_ARGS__)
static inline void PxReportv(BOOL doLog, char const *file, int line, NSString *prefix, NSString *fmt, va_list argList) {
if (doLog) {
NSString *fileNameWithExtension = [[NSString stringWithFormat:#"%s", file] lastPathComponent];
#ifdef NO_LOG
NSString *fileName = [fileNameWithExtension stringByDeletingPathExtension];
char *f = TOSTRING(NO_LOG);
NSArray *comps = [[[NSString alloc] initWithFormat:#"%s", f] componentsSeparatedByString:#","];
for (NSString *except in comps) {
if ([except isEqualToString:fileName]) {
return;
}
}
#endif
vprintf([[[NSString alloc] initWithFormat:[[NSString alloc] initWithFormat:#"%# <%# [%d]> %#\n", prefix, fileNameWithExtension, line, fmt] arguments:argList] cStringUsingEncoding:NSUTF8StringEncoding], NULL);
}
}
static inline void PxReport(BOOL doLog, char const *file, int line, NSString *prefix, NSString *fmt, ...) {
va_list ap;
va_start(ap, fmt);
PxReportv(doLog, file, line, prefix, fmt, ap);
va_end(ap);
}
#define PxError(...) PxReport(YES, __FILE__, __LINE__, #"[ERROR]", __VA_ARGS__)
#ifdef DEBUG
#define PxDebug(...) PxReport(YES, __FILE__, __LINE__, #"[DEBUG]", __VA_ARGS__)
#define NSLog(...) PxReport(YES, __FILE__, __LINE__, #"", __VA_ARGS__)
#else
#define PxDebug(...)
#define NSLog(...)
#endif
Add this:
#define NO_LOG 1
before #importing the file you've shown above.
BTW a better implementation would define PxDebug() and NSLog() to nothing if NO_LOG was defined...
that is quite a verbose solution, i made one that is a lot neater than that
#ifndef DebugLog_h
#define DebugLog_h
#if DEBUG
#define DLog(...) do{\
printf("[%s:%d]", __FUNCTION__, __LINE__);\
NSString *_S_ = [NSString stringWithFormat:__VA_ARGS__];\
printf(" %s\n",[_S_ cStringUsingEncoding:NSUTF8StringEncoding]);\
}while(0);
#else
#define DLog(...)
#endif
#endif
that will print the line number, class and function it came from
eg:
Dlog(#"hello %d", 123);
[-[SomeViewController viewWillAppear:]:91] hello 123
edit: if you add the file to your projectname-Prefix.pch file, then you can use it without having to include it everywhere
and it will automatically be taken out of release builds, because DEBUG is defined as a project definition automatically when its in debug mode

Resources