Diagrama MVC – IOS

O aplicatie bine facuta IOS respecta principiile programarii MVC – Model – View – Controller.
O explicatie vizuala foarte buna despre “circulatia” in interiorul unei aplicatii IOS in poza de mai jos:
Model MVC IOS

In cazul in care datele din Model sunt aduse dintr-un JSON, exista posibilitatea ca ceea ce se doreste a se afisa in View sa NU existe la momentul afisarii, acest lucru datorandu-se faptului ca initializarea din JSON se face asincron:

MVC JSON fara NSNotification

Pentru a remedia acest aspect, avem nevoie de o intarziere. O intarziere care este de fapt o notificare pe care, atunci cand apare, o va capta controller-ul si va “da drumul” la executarea elementelor de View:

Model MVC cu NSNotification

Share Button

Completion handler în main thread

De fapt, vreau să am content-ul de la JSON-ul de twitter afișat atunci cănd rulez aplicația.
Cu secvența de mai jos – trebuie sa dau click

dispatch_async(dispatch_get_main_queue(), ^{
// NSURLSession – model prima faza
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSError *jsonParsingError = nil;
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParsingError];
//din JSON in NSDictionary doar itemul STATUSES
self.results = jsonResults[@”statuses”];
[self.tableView reloadData];

}];
[dataTask resume];
});

De ce?
Pentru că UI-ul trebuie să fie actualizat doar din main thread. Dacă testez cu [[NSThread currentThread] isMainThread], aflu că nu sunt în main thread.
Așa că modific codul astfel:


[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSError *jsonParsingError = nil;
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParsingError];
if (jsonParsingError)
{
NSLog(@”Eroare la JSON=%@”, jsonParsingError);
}
self.results = jsonResults[@”statuses”];
//din JSON in NSDictionary doar itemul STATUSES
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
if ([[NSThread currentThread] isMainThread]){
NSLog(@”Sunt in main thread”);
}
else{
NSLog(@”Nu sunt in main thread”);
}
});
}];
[dataTask resume];

În acest moment aplicația funcționează perfect.

Share Button

Marcare URLs, hashtag și mention în IOS

Am de identificat într-un tweet URLs, hashtag-uri și mention tag-uri. Dacă # și @ le identific prin regular expression, pentru URLs folosesc o clasă foarte tare din IOS numită NSDataDetector, instanța uitându-se doar după ce-i specific eu: URLs.


NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:stringWithTags];
//identifica URLs in tweet.
NSError *error = NULL;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error];
NSArray *matchesOfURLS = [detector matchesInString:stringWithTags
options:0
range:NSMakeRange(0, [stringWithTags length])];
for (NSTextCheckingResult *match in matchesOfURLS) {
NSRange wordRange = [match range];
[attString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:wordRange];
}

//identifica # si @ in tweet.
NSArray *matches = [self.regex matchesInString:stringWithTags options:0 range:NSMakeRange(0, stringWithTags.length)];
for (NSTextCheckingResult *match in matches) {
// wordRange -> length= lungime cuvant si location=poz in string
NSRange wordRange = [match rangeAtIndex:1];
NSString* word = [stringWithTags substringWithRange:wordRange];

if ([self sirul:word contineCaracter:’@’]){
[attString addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:wordRange];
}
else
{
[attString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:wordRange];

}

}

Share Button

IOS – colturi rotunjite si borduri la poza de profil

Fie un UIImageView care va “încarca” o imagine. În cazul meu, am folosit imageTAView pentru a încarca poză de profil pentru aplicația mea de Twitter.
@property (nonatomic,strong) UIImageView *imageTAView;

In .m definim următoarele:
self.imageTAView.layer.cornerRadius = self.imageTAView.frame.size.width / 2;
self.imageTAView.clipsToBounds = YES;

Pentru a transforma imaginea pătrată în formă circulară definim raza circulara a layer-ului ca fiind jumătate din lățimea layerului pătrat. clipsToBounds “pune” masca nou-creată peste layerul inițiat pătrat.

Aplicarea bordurii se realizează cu borderWidth, proprietate din clasa CALayer, după cum urmează:

self.imageTAView.layer.borderWidth = 3.0f;
self.imageTAView.layer.borderColor = [UIColor lightGrayColor].CGColor;

Share Button