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

Cum setăm AppIcon pentru o aplicație IOS?

1. realizăm/căutăm o imagine – foarte bună ar fi una 1024x1024px.
2. încărcăm imaginea pe https://makeappicon.com
3. folosim o adresă de email pentru a primi arhiva cu icon-urile realizate. Nu trebuie să ne batem capul cu imagini 2x sau 3x. Știe Ben Cheng ce are de făcut cu poza.
4. în arhivă sunt două foldere IOS și Android. Din IOS luăm fodlerul AppIcon.appiconset și-l copiem în proiectul nostru.

Obs. Pentru informații despre dimensiunile icon-urilor avem acest tabel.

Share Button