I have created an app which i only want to work if the user is within a specific area (i.e. i only want the user to be able to sent an email if they are within a specific state of the country)
can some please either-
a) point me in the direction of a tutorial on how to set up a GPS boundary, and how to check if a user is within said GPS boundary
or
b) write an example for creating a GPS area, and how to check if the user is within the area.
i have the latitude and longitude of the user stored to variables.
here is my location manager code:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation: %#", newLocation);
CLLocation *currentLocation = newLocation;
if (currentLocation != nil) {
longditute = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
Latitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
}
// Stop Location Manager
[locationManager stopUpdatingLocation];
}
and my email code:
-(IBAction)actionEmailComposer{
if ([MFMailComposeViewController canSendMail]) {
if ([witnessResponse isEqual: #"Yes"]) {
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc]init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:[NSString stringWithFormat:#"Dob in a Hoon Report(Y)"]];
[mailViewController setMessageBody:[NSString stringWithFormat:#"Am I prepared to be called upon as a witness?: %# \n Rego Number: %# \n Vehicle Make: %# \n Vehicle Colour: %# \n Vehicle Type: %# \n Incident Date: %# \n Incident Time: %# \n Incident Location: %# \n Do I know the Driver?: %# \n Drivers Name (if Known) %# \n Driver Gender: %# \n Description of Incident: %# \n Name of Person Reporting Incident: %# \n Contact Number: %# \n" , witnessResponse, regoNumber.text, vehilceMake.text, vehilceColour.text, vehicleType.text, incidentDate.text, incidentTime.text, location.text, driverKnownResponse, driverName.text, driverGenderResponse, additionalInfo.text, usersName.text, usersPhoneNumber.text] isHTML:NO];
[self presentViewController:mailViewController animated:YES completion:nil];
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
[mailViewController addAttachmentData:imageData mimeType:#"image/jpg" fileName: [NSString stringWithFormat:#"Dob in a Hoon %# , %#.jpg", Latitude,longditute]];
[mailViewController setToRecipients:toRecipients];
} else {
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc]init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:[NSString stringWithFormat:#"Dob in a Hoon Report(N)"]];
[mailViewController setMessageBody:[NSString stringWithFormat:#"Am I prepared to be called upon as a witness?: %# \n Rego Number: %# \n Vehicle Make: %# \n Vehicle Colour: %# \n Vehicle Type: %# \n Incident Date: %# \n Incident Time: %# \n Incident Location: %# \n Do I know the Driver?: %# \n Drivers Name (if Known) %# \n Driver Gender: %# \n Description of Incident: %# \n Name of Person Reporting Incident: %# \n Contact Number: %# \n" , witnessResponse, regoNumber.text, vehilceMake.text, vehilceColour.text, vehicleType.text, incidentDate.text, incidentTime.text, location.text, driverKnownResponse, driverName.text, driverGenderResponse, additionalInfo.text, usersName.text, usersPhoneNumber.text] isHTML:NO];
[self presentViewController:mailViewController animated:YES completion:nil];
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
[mailViewController addAttachmentData:imageData mimeType:#"image/jpg" fileName: [NSString stringWithFormat:#"Dob in a Hoon %# , %#", Latitude,longditute]];
[mailViewController setToRecipients:toRecipients];
}
}
else{
NSLog(#"Device is unable to send email");
}
}
my goal is: if the person is outside the area, i want to display a UIAlert informing the user they are outside the area. If the person is inside the area, it will go through the email set up.
You want the CLLocationManager, and methods like startMonitoringForRegion:, which uses CLCircularRegion objects to define geographic regions.
If you look in the Xcode docs for startMonitoringForRegion, it has a link to a demo project called "Regions", which should get you started.
Related
I am working on Action Extension Objective C. I have successfully created Extension for share recent contact in my Extension. In that I am getting v Card String. How can I get Mobile Number from v Card String. Any help would be appreciated.
Using contactsWithData:error: class method of CNContactVCardSerialization, you can retrieve info from a vCard.
It's from Contacts.framework, available since iOS9.
For earlier version, you can use AddressBook.framework. You can read info here.
NSError *errorVCF;
NSArray *allContacts = [CNContactVCardSerialization contactsWithData:[contactStr dataUsingEncoding:NSUTF8StringEncoding] error:&errorVCF];
if (!errorVCF)
{
NSMutableString *results = [[NSMutableString alloc] init];
//NSLog(#"AllContacts: %#", allContacts);
for (CNContact *aContact in allContacts)
{
NSArray *phonesNumbers = [aContact phoneNumbers];
for (CNLabeledValue *aValue in phonesNumbers)
{
CNPhoneNumber *phoneNumber = [aValue value];
[results appendFormat:#"%# %#\n", [aValue label], [phoneNumber stringValue]];
}
}
NSLog(#"Final: %#", results);
}
My app finds the user's location, and shows the address in a label. The problem is that if something doesn't exist at a certain place, a postal code for example, then the line says (null). How do I make that line blank? I suppose it has to be set to nil somehow, somewhere...
Please help!
Here's my code:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"Location: %#", newLocation);
CLLocation *currentLocation = newLocation;
[geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (error == nil && [placemarks count] > 0) {
placeMark = [placemarks lastObject];
NSString *locationString = [NSString stringWithFormat:#"%# %#\n%# %#\n%#\n%#",
placeMark.subThoroughfare,
placeMark.thoroughfare,
placeMark.postalCode,
placeMark.locality,
placeMark.administrativeArea,
placeMark.country];
locationLabel.text = locationString;
}
else {
NSLog(#"%#", error.debugDescription);
}
}];
}
This code checks all fields for nil (which causes the <null> output) and replaces nil values with an empty string.
NSString *locationString = [NSString stringWithFormat:#"%# %#\n%# %#\n%#\n%#",
placeMark.subThoroughfare ?: #"",
placeMark.thoroughfare ?: #"",
placeMark.postalCode ?: #"",
placeMark.locality ?: #"",
placeMark.administrativeArea ?: #"",
placeMark.country ?: #""];
Quick and (very) dirty solution, but ones may find it readable:
substitute placeMark.postalCode,
with
placeMark.postalCode ? placeMark.postalCode : #"",
for each element you want nothing (or whatever other string) to appear in case of nil.
Or just write custom code to check for each element in local variables.
--
Edit:
In the remote case that you actually have a string containing "(null)" the you may want to consider checking for this value substituting again each line with:
[placeMark.postalCode isEqualToString:#"(null)"]? #"" : placeMark.postalCode,
consider anyway that you should really take care of this earlier in your logic, probably some parsing went wrong when creating the placeMark object string members.
You really need to write code to check for missing fields and handle them appropriately.
Consider that if some of the items are missing there may be blank lines in the resulting string.
I am at the part of my register process where I would like to confirm if the email given by the user exists and is not already taken.
So far, I have the regex set and customized to how I want it (I am limiting the user to a student email address).
- (BOOL)validateEmail:(NSString *)emailStr {
NSString *emailRegex = #"[A-Za-z]+\\.[A-Za-z]+#[ace]+\\.[tamut]+\\.[edu]";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegex];
[self checkEmailAndDisplayAlert];
return [emailTest evaluateWithObject:emailStr];
}
I throw an alert if the email is not acceptable.
- (void)checkEmailAndDisplayAlert {
if(![self validateEmail:[_email text]]) {
[self.email becomeFirstResponder];
// user entered invalid email address
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Enter a valid email address." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
} else {
// user entered valid email address
[self registerNewUser];
}
}
If I enter an email that does not meet the regex requirements, the proper alert is not shown, and I am still allowed to pass through the registration as a new user. What am I doing wrong?
Please don't hold back on any feedback, I am new to programming and this is something I need to know, no excuses.
In your validateEmail method, you call checkEmailAndDisplayAlert ([self checkEmailAndDisplayAlert];), and it also calls validateEmail. I'd delete [self checkEmailAndDisplayAlert]; to avoid endless loops.
Also, try changing the regex to
NSString *emailRegex = #"^[A-Za-z]+\\.[A-Za-z]+#ace\\.tamut\\.edu$";
The function to check validity could also look like:
- (BOOL)validateEmail:(NSString *)emailStr
{
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^[a-z]+\\.[a-z]+#ace\\.tamut\\.edu$" options:NSRegularExpressionCaseInsensitive error:&error];
NSAssert(regex, #"Unable to create regular expression");
NSRange txtRng = NSMakeRange(0, emailStr.length);
NSRange matchRng = [regex rangeOfFirstMatchInString:emailStr options:NSMatchingReportProgress range:txtRng];
BOOL validated = NO;
if (matchRng.location != NSNotFound)
validated = YES; // Match found
return validated;
}
^ and $ are added at the beginning anf end of the regex pattern to enable whole string search.
I have this code
NSString *messageBody = [NSString stringWithFormat:#"Name: %#\nCompany/Institution: %#\nAddress: %#\nCity: %#\nCountry: %#\nContact Number: %#\nE-Mail: %#\n \n \n Message: %#", rName.text, rCompany.text, rAddress.text, rCity.text, rCountry.text, rContactNumber.text, rEmail.text, rDescription.text];
[tempMailCompose setMessageBody:messageBody isHTML:NO];
to fill contents on the MFMailComposeViewController Now what I want to do is to make the Name, Address, City, Country, Contact Number, E-Mail, and Message to be bold. What I did was to insert <strong> but the result was wrong it also displays <strong>as text.
How will I able to bold it?
Try this
NSString *messageBody = [NSString stringWithFormat:#"Name: <b>%#</b><br/>Company/Institution: <b>%#</b><br/>Address: <b>%#</b><br/>City: <b>%#</b><br/>Country: <b>%#</b><br/>Contact Number: <b>%#</b><br/>E-Mail: <b>%#</b><br/> <br/> <br/> Message: <b>%#</b>", rName.text, rCompany.text, rAddress.text, rCity.text, rCountry.text, rContactNumber.text, rEmail.text, rDescription.text];
[tempMailCompose setMessageBody:messageBody isHTML:YES];
My company has an iOS app that interfaces directly with Salesforce, with one major drawback. When a user attempts to upload an illegal character, the app hangs, returns bad values, or results in some other erratic behavior.
I found a really handy piece of code out in the mystical interwebs (thanks, MailDrop), that filters a string and escapes those illegal characters with a forward slash. It then returns the value in a string, ready for upserting/querying.
One thing I'm really having trouble with is getting this to work with our application, though. Our data is stored in a dictionary and is written to in a variety of ways (querying the server, or manual input), and at various times in the application's life cycle. I'm not quite sure how to invoke this nifty 'escapeSosl' in the most efficient method. Is there a way that I can escape these characters every time I write to Core Data? What I'm most afraid of is going through the app and calling this hundreds of times.
Here is the escaping method:
- (NSString *)escapeSosl:(NSString *)src {
// from docs, these are all reserved
NSArray *reserved = [NSArray arrayWithObjects:#"\\", #"&", #"|", #"!", #"{", #"}", #"[", #"]", #"^", #"~", #"*:", #":", #"'" ,#"\"", #"+", #"-", nil];
NSMutableString *s = [NSMutableString stringWithString:src];
NSString *r;
NSEnumerator *e = [reserved objectEnumerator];
while (r = [e nextObject])
[s replaceOccurrencesOfString:r withString:[NSString stringWithFormat:#"\\%#", r] options:NSLiteralSearch range:NSMakeRange(0, [s length])];
return s;
}
What I find complicated is the timing of these escapings, and how to apply that to each situation. For instance, the app queries Salesforce for an Account using a location that was either manually entered or found via reverse geocoding. Here is an example of the app requesting data from the Salesforce Server:
-(void)checkServerForLeadMatchingAddressOnAccount:(SFAccount *)account {
currentAccount = account;
//Parse the account location data, removing the last word in the `street` object
NSString *street = account.shippingStreetAddress;
NSMutableArray *streetArray = [[street componentsSeparatedByString:#" "] mutableCopy];
[streetArray removeLastObject];
street = [streetArray componentsJoinedByString:#" "];
street = [street stringByAppendingString:#"_%"];
NSString *city = account.shippingCity;
NSString *state = account.shippingState;
NSString *zip = account.shippingZIP;
//Check for a matching lead on the server. User the callback methods to proceed (either create new data on the server or download to the device
NSLog(#"is connected: %i", self.isConnectedToServer);
if (self.isConnectedToServer){
requestCheckForLead = [[SFRestAPI sharedInstance] requestForQuery:[NSString stringWithFormat:#"SELECT ID, Company, Name, Street, City, State, PostalCode, Phone FROM Lead WHERE PostalCode = '%#' AND Street LIKE '%#' AND City = '%#' AND State = '%#'", zip, street, city, state]];
[[SFRestAPI sharedInstance] send:requestCheckForLead delegate:self];
openTasks++;
} else {
NSLog(#"I can't connect");
[self.serverDelegate serverObjectManager:self communicationSuccessful:NO withResponse:#"Could not connect to the server."];
}
Another area where I might escape characters is right before initiating an upload to the server. There are a couple things that get uploaded, including an Account, the Account's Contact (1:1 rel.), the Account's Opportunity (1:1 rel.), and an Opportunity's Current Service Levels (1:many rel).
Here is an example of the Contact associated with an Account - it uses both Strings and dictionary references, but has some additional logic for parsing firstName from lastName. I'd like to escape the data in a way that I do not need to worry about the timing of these manipulations.
NSMutableDictionary *contactDict = [NSMutableDictionary new];
if (myAccount.contact.email) {
[contactDict setObject:myAccount.contact.email forKey:#"Email"];
} else {
[contactDict setObject:#"" forKey:#"Email"];
}
if (myAccount.contact.name) {
//Split name in two
NSArray *nameArray = [myAccount.contact.name componentsSeparatedByString:#" "];
NSString *firstName = [nameArray objectAtIndex:0];
NSString *lastName = [nameArray lastObject];
[contactDict setObject:firstName forKey:#"firstName"];
[contactDict setObject:lastName forKey:#"lastName"];
} else {
[contactDict setObject:#"" forKey:#"firstName"];
[contactDict setObject:#"" forKey:#"lastName"];
}
if (myAccount.contact.phone){
[contactDict setObject:myAccount.contact.phone forKey:#"Phone"];
} else {
[contactDict setObject:#"" forKey:#"Phone"];
}
updateContactRequest = [[SFRestAPI sharedInstance] requestForUpdateWithObjectType:#"Contact" objectId:myAccount.createdContactID fields:contactDict];
[[SFRestAPI sharedInstance] send:updateContactRequest delegate:self];
So this may seem like a bit of a large question, but does anyone have some pointers as to how I could escape characters in these various dictionaries, using something similar to the 'escapeSosl' code I included above, whenever things are written to core data?
In this line you build your query
requestCheckForLead = [[SFRestAPI sharedInstance] requestForQuery:[NSString stringWithFormat:#"SELECT ID, Company, Name, Street, City, State, PostalCode, Phone FROM Lead WHERE PostalCode = '%#' AND Street LIKE '%#' AND City = '%#' AND State = '%#'", zip, street, city, state]];
instead of passing street as the parameter pass [self escapeSosl:street] and so on for the other params.