How to compare the strings? - objective-c

In my project i am adding many words to a list from another view controller and i need to check that the words cannot be same in the list.
Here is the code ,please help where i need to do that
-(IBAction)save:(id)sender{
if ([listName.text isEqualToString:#""]) {
UIAlertView *error = [[UIAlertView alloc] initWithTitle:nil message:#"Please enter List Name." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[error show];
} else if (self.newlist) {
if (listName.text.length > 0 ) {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"YYYY-MM-dd"];
NSString *dateString = [dateFormatter stringFromDate:currDate];
if (notification.on ) {
NSString *dateStr = [[NSString alloc] initWithFormat:#"%# %#",dateString, time.text ];
[self saveList:dateStr:dateString];
[self saveListImages];
[self getlistdata];
}else {
[self saveList:#"2000-01-01 00:00":dateString];
}
}else{
[listName becomeFirstResponder];
}
}
}

Add your string in a mutable array and call below comparator to check for duplicates. Below code ensures case insensitive checks so it won't allow TEST and test go in the same array.
NSMutableArray *myArray = [NSMutableArray arrayWithArray:#[#"TEST", #"Data"]];
NSString *testString = #"Test";
NSInteger index = [myArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return (BOOL)([obj caseInsensitiveCompare:testString] == NSOrderedSame);
}];
if (index != NSNotFound) {
NSLog(#"String already entered. Throw error");
} else {
[myArray addObject:testString];
}

NSOrderedSet *uniqueWordSet = [NSOrderedSet orderedSetWithArray:arrayWithDuplicates];
NSArray *unwiqueWordList = uniqueWordSet.array; // If you need it as array

Related

Create ICS with objective C

I am writing an app for students at my university. At this point I want to export the lessons in the schedule as an ics-file. I have wrote something that works with csv-files, but now I want the same for ics.
The problem is that iCal at my Mac doesn't want the in-app-created ics-files from this code:
-(NSURL*)getFileUrl
{
NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"Stundenplan-%#.ics", _MatrNr]];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSError *error = nil;
[[self getICSData] writeToURL:fileUrl atomically:YES];
if (error) {
NSLog(#"Error while writing to File: %#", [error localizedDescription]);
}
return fileUrl;
}
-(NSData*)getICSData
{
NSMutableString *erg = [[NSMutableString alloc] init];
NSDate *aktDatum = [NSDate date];
[erg appendString:[NSString stringWithFormat:#"BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//www.htw-dresden.de//iOS//DE\nMETHOD:PUBLISH\n"]];
for (Stunde *this in _daten) {
NSString *titel = [this.titel stringByReplacingOccurrencesOfString:#"," withString:#"\\, "];
NSString *dozent = [this.dozent stringByReplacingOccurrencesOfString:#"," withString:#"\\, "];
NSString *uuid = [[NSUUID UUID] UUIDString];
[erg appendString:[NSString stringWithFormat:#"BEGIN:VEVENT\nUID:%#\n", uuid]];
[erg appendString:[NSString stringWithFormat:#"DTSTART:%#T%#Z\n",[self nurTagFromDate:this.anfang], [self nurUhrzeigFromDate:this.anfang]]];
[erg appendString:[NSString stringWithFormat:#"DTEND:%#T%#Z\n",[self nurTagFromDate:this.ende], [self nurUhrzeigFromDate:this.ende]]];
[erg appendString:[NSString stringWithFormat:#"LAST-MODIFIED:%#T%#Z\nSEQUENCE:0\nSTATUS:CONFIRMED\n", [self nurTagFromDate:aktDatum], [self nurUhrzeigFromDate:aktDatum]]];
[erg appendString:[NSString stringWithFormat:#"SUMMARY:%#\nDESCRIPTION:%#\nLOCATION:%#\nEND:VEVENT\n", titel, dozent, this.raum]];
}
[erg appendString:#"END:VCALENDER"];
NSData *ret = [erg dataUsingEncoding:NSUTF8StringEncoding];
return ret;
}
In the getFileUrl I want to return a URL to the file created in there. This function calls the getICSData function that goes through my array (_daten) and creates for every Stunde object this ics-"code".
For help I have these NSDate formatting functions:
-(NSString*)nurTagFromDate:(NSDate*)date
{
NSDateFormatter *nurTag = [[NSDateFormatter alloc] init];
[nurTag setDateFormat:#"yyyyMMdd"];
return [nurTag stringFromDate:date];
}
-(NSString*)nurUhrzeigFromDate:(NSDate*)date
{
NSDateFormatter *nurTag = [[NSDateFormatter alloc] init];
[nurTag setDateFormat:#"HHmmss"];
return [nurTag stringFromDate:date];
}
As output I get something like this:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//www.htw-dresden.de//iOS//DE
METHOD:PUBLISH
BEGIN:VEVENT
UID:CCCAC9B3-E056-47E3-A63B-F2FE2C3BA454
DTSTART:20140318T111000Z
DTEND:20140318T124000Z
LAST-MODIFIED:20140429T182723Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Internet-Technologien I
DESCRIPTION:Vogt\, J.
LOCATION:Z 254
END:VEVENT
.
.
.
END:VCALENDER
But the calendar app at my Mac don't want to open the file...
It would be great if some of you will have an Idea :)
Replace this line:
[erg appendString:#"END:VCALENDER"];
With this:
[erg appendString:#"END:VCALENDAR"];
Notice the typo in VCALENDAR.
You may find this iCal file validator useful.

Parse PFObject ID to map annotation title & subtitle

I'm using the parse framework to collect objects in a class and display them on a map. Currently, the annotation titles display the "CreatedAt" string, and the subtitles display the "coordinates". How can I change the title and subtitle to another PFObject ID that I've set? I've based a lot of my code on the GeoLocations app that Parse have supplied. The code is as follows:
#interface GeoPointAnnotation()
#property (nonatomic, strong) PFObject *object;
#end
#implementation GeoPointAnnotation
- (id)initWithObject:(PFObject *)aObject {
self = [super init];
if (self) {
_object = aObject;
PFGeoPoint *geoPoint = self.object[#"coordinates"];
[self setGeoPoint:geoPoint];
}
return self;
}
- (void)setGeoPoint:(PFGeoPoint *)geoPoint {
_coordinate = CLLocationCoordinate2DMake(geoPoint.latitude, geoPoint.longitude);
static NSDateFormatter *dateFormatter = nil;
if (dateFormatter == nil) {
dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeStyle = NSDateFormatterMediumStyle;
dateFormatter.dateStyle = NSDateFormatterMediumStyle;
}
static NSNumberFormatter *numberFormatter = nil;
if (numberFormatter == nil) {
numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
numberFormatter.maximumFractionDigits = 3;
}
_title = [dateFormatter stringForObjectValue:self.object.createdAt];
_subtitle = [NSString stringWithFormat:#"%#, %#", [numberFormatter stringFromNumber:[NSNumber numberWithDouble:geoPoint.latitude]],
[numberFormatter stringFromNumber:[NSNumber numberWithDouble:geoPoint.longitude]]];
}
#end
Fixed it by replacing some of the code with this:
static NSString *dateFormatter = nil;
if (dateFormatter == nil) {
dateFormatter = [[NSString alloc] init];
}
and then this:
_title = [dateFormatter stringByAppendingString:self.object[#"Name"]];
_subtitle = [dateFormatter stringByAppendingString:self.object[#"Location"]];

Sorting a PFQuery by counting objects in array

What I am doing is in my Parse query, I check to see which posts have been check marked (liked) in the last 7 days. I then remove the dates of those that haven't. This is working fine. Now my problem is that I need to sort them in my UITableView in descending order of how many dates are in the array but my sortedArrayUsingComparator isn't working. Im new to Objective C so its probably something easy but idk. Here's my code
- (PFQuery *)queryForParse {
PFQuery *query1 = [PFQuery queryWithClassName:self.parseClassName];
//[query1 selectKeys: [NSArray arrayWithContentsOfFile:[ NSString #"checkMark"]]];
[query1 whereKey:#"location" nearGeoPoint:[PFGeoPoint geoPointWithLatitude:[LocationController sharedSingleton].locationManager.location.coordinate.latitude longitude:[LocationController sharedSingleton].locationManager.location.coordinate.longitude] withinMiles:50];
[query1 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error){
placesArray = [[NSMutableArray alloc] initWithArray:objects];
NSMutableArray *toDelete = [NSMutableArray array];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyyMMdd"];
for (PFObject *tempObject in placesArray){
checkDates = [[NSMutableArray alloc] initWithArray:[tempObject objectForKey:#"checkMarkDates"]];
for (NSString *dateString in checkDates) {
NSDate *date = [dateFormat dateFromString: dateString];
if ([date timeIntervalSinceNow] > -604800){
[toDelete addObject:dateString];
}
}
[checkDates removeObjectsInArray:toDelete];
[tempObject removeObjectsInArray:checkDates forKey:#"checkMarkDates"];
sortedArray = [placesArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSUInteger *first = [[obj1 objectForKey:#"checkMarkDates"] count];
NSNumber *f = [[NSNumber alloc] initWithInteger:first];
NSUInteger *second = [[obj2 objectForKey:#"checkMarkDates"] count];
NSNumber *s = [[NSNumber alloc] initWithInteger:second];
return [f compare:s];
}];
}
NSLog(#"%#", sortedArray);
}
[placesTable reloadData];
}];
return query1;
}
Figured it out. I had the sortedArrayUsingComparator in the for statement. I moved it out and it works fine now.

Fix unicode characters in NSString

I am getting a string response from the Google Directions API that contains characters that are supposed to represent a different-language character. Similiar to Ƨ³, similiar to these type of characters. I think the characters are portugese, but anyways my string contains like this:
\U00e3o
(I am not sure if those are zeroes or 'O's)
I am not sure what the technical term for these characters are, but how can I fix them in my string so they print properly.
Thank you
UPDATE:
I have updated my question title with the correct term 'unicode'.
I have checked a few questions:
NSString Unicode display
Detect Unicode characters in NSString on iPhone
iOS HTML Unicode to NSString?
And a few others. I have followed the answer, but the unicode characters are not fixed.
UPDATE:
Here is my code to get the response from GDirection.
Forming the request and getting a response:
AFHTTPClient *_httpClient = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://maps.googleapis.com/"]];
[_httpClient registerHTTPOperationClass: [AFJSONRequestOperation class]];
[_httpClient setDefaultHeader:#"Accept" value:#"application/json"];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[parameters setObject:[NSString stringWithFormat:#"%f,%f", location.coordinate.latitude, location.coordinate.longitude] forKey:#"origin"];
[parameters setObject:[NSString stringWithFormat:#"%f,%f", location2.coordinate.latitude, location2.coordinate.longitude] forKey:#"destination"];
[parameters setObject:#"false" forKey:#"sensor"];
[parameters setObject:#"driving" forKey:#"mode"];
[parameters setObject:#"metric" forKey: #"units"];
NSMutableURLRequest *request = [_httpClient requestWithMethod:#"GET" path: #"maps/api/directions/json" parameters:parameters];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
AFHTTPRequestOperation *operation = [_httpClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSInteger statusCode = operation.response.statusCode;
if (statusCode == 200) {
[self parseResponse:responseObject];
} else {
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { }];
[_httpClient enqueueHTTPRequestOperation:operation];
}
Retrieving information from response object:
- (void)parseResponse:(NSDictionary *)response {
NSString *status = [response objectForKey: #"status"];
if (![status isEqualToString: #"OK"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat: #"Google Directions Response Status: %#", status] delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[alert show];
}
else {
NSArray *routes = [response objectForKey:#"routes"];
NSDictionary *routePath = [routes lastObject];
if (routePath) {
NSString *overviewPolyline = [[routePath objectForKey: #"overview_polyline"] objectForKey:#"points"];
legs = [routePath valueForKey: #"legs"];
if (legs) {
/* DIRECTION SET ================================================================================================================================
*/
directionOverview = [[NSMutableDictionary alloc] init];
NSString *legsDis = [NSString stringWithFormat: #"%#", [[legs valueForKey: #"distance"] valueForKey: #"text"]];
NSString *kmDistance = [self cutStringToPreference: legsDis];
if (kmDistance) {
[directionOverview setObject:kmDistance forKey: #"distance"];
milesLabel.text = kmDistance;
milesLabel.font = [UIFont fontWithName:#"interstate" size: 20.0];
}
NSString *durationText = [NSString stringWithFormat: #"%#", [[legs valueForKey: #"duration"] valueForKey: #"text"]];
durationText = [self cutStringToPreference: durationText];
if (durationText) {
[directionOverview setObject:durationText forKey: #"duration"];
}
NSString *startAddress = [NSString stringWithFormat: #"%#", [legs valueForKey: #"start_address"]];
startAddress = [self cutStringToPreference: startAddress];
NSString *endAddress = [NSString stringWithFormat: #"%#", [legs valueForKey: #"end_address"]];
endAddress = [self cutStringToPreference: endAddress];
[directionOverview setObject:startAddress forKey: #"origin"];
[directionOverview setObject:endAddress forKey: #"destination"];
NSArray *steps = [legs valueForKey: #"steps"];
if (steps) {
instructionArray = [[NSMutableArray alloc] init];
durationArray = [[NSMutableArray alloc] init];
distanceArray = [[NSMutableArray alloc] init];
int number = [[[steps lastObject] valueForKey: #"html_instructions"] count];
for (int i = 1; i <= number; ++i) {
NSString *instruction = [[[steps lastObject] valueForKey: #"html_instructions"] objectAtIndex: i-1];
instruction = [self cutStringToPreference: instruction];
instruction = [self flattenHTML: instruction];
instruction = [self stringByDecodingHTMLEntitiesInString: instruction];
[instructionArray addObject: instruction];
NSString *distance = [[[[steps lastObject] valueForKey: #"distance"] objectAtIndex: i-1] valueForKey: #"text"];
[distanceArray addObject: distance];
NSString *duration = [[[[steps lastObject] valueForKey: #"duration"] objectAtIndex: i-1] valueForKey: #"text"];
[durationArray addObject: duration];
}
}
}
_path = [self decodePolyLine:overviewPolyline];
NSInteger numberOfSteps = _path.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [_path objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[self.mapView addOverlay:polyLine];
}
}
}
Displaying the text in a label:
NSString *overviewAddressText = [NSString stringWithFormat: #"%# to %#", [directionOverview objectForKey: #"origin"], [directionOverview objectForKey: #"destination"]];
overviewAddress.text = overviewAddressText;
UPDATE:
Image of label
So as you can see, in the label, the text contains this kind of substring: S/U00e3o, which is a word that has an unsupported character. How can I fix that so that unicode turns into this: São

Memory Leaks in UIPickerView using sqlite

I'm adding self.notes array to a UIPickerView. This is how I'm setting the array:
NSMutableArray *notesArray = [[NSMutableArray alloc] init];
[notesArray addObject:#"-"];
[notesArray addObjectsFromArray:[dbManager getTableValues:#"Notes"]];
self.notes = notesArray;
[notesArray release];
The info for the UIPickerView is taken from the database in this method:
-(NSMutableArray *)getTableValues:(NSString *)table
{
NSMutableArray *valuesArray = [[NSMutableArray alloc] init];
if (sqlite3_open([self.databasePath UTF8String], &database) != SQLITE_OK)
{
sqlite3_close(database);
NSAssert(0, #"Failed to open database");
}
else
{
NSString *query = [[NSString alloc] initWithFormat:#"SELECT value FROM %#", table];
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW) {
NSString *value =[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 0)];
[valuesArray addObject:value];
[value release];
}
sqlite3_reset(statement);
}
[query release];
sqlite3_finalize(statement);
sqlite3_close(database);
}
return valuesArray;
}
But I keep getting memory leaks in Instruments for these lines:
NSMutableArray *valuesArray = [[NSMutableArray alloc] init];
and
[valuesArray addObject:value];
What am I doing wrong here?
Thanks for your help!
Instead of NSMutableArray *valuesArray = [[NSMutableArray alloc] init]; use this line:
NSMutableArray *valuesArray = [NSMutableArray array];
As for the [valuesArray addObject:value]; leak, change your code to this:
[valuesArray addObject:value];
value = nil;
You are returning valuesArray from the getTableValues which is allocated but not released. You can not release it in the method as the caller still needs it. The correct way is to autorelease it.
return [valuesArray autorelease];
And also you don't need to release value string after adding it to valuesArray as it is created with a convenient constructor.