Debug casting class


id DebugCastCpp(id sourceClass, Class cl)
{
	if (sourceClass != nil)
	{
		if (![sourceClass isKindOfClass: cl])
		{
            NSLog(@"%@", [NSString stringWithFormat: @"The cast is invalid (%@ to %@)", [sourceClass class], cl]);
			@throw [NSException exceptionWithName:@"CastException" reason: [NSString stringWithFormat: @"The cast is invalid (%@ to %@)", [sourceClass class], cl] userInfo:nil];
		}
	}
	
	return sourceClass;
}



Advertisements

Reverse NSString with Objective-C

Objective-C ensure you more possibilities when you’re manipulating existing objects like NSArray, NSString, NSDictionary etc. Some API functions can be done less code and some other snippets really mess.

Here is the reverse string block code

NSString *myString = @"abcdefghijklmnopqrstuvwxyz";
NSMutableString *reversedString = [NSMutableString stringWithCapacity:[myString length]];

[myString enumerateSubstringsInRange:NSMakeRange(0,[myString length]) 
                             options:(NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences)
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                            [reversedString appendString:substring];
                        }];

Before I learn reverse string block syntax I was doing this iterate trough all exist string length and after the range this string I was add these reversed string in a mutable array. Here is the my old approach

// first retrieve the text of textField1
NSString *myString = textField1.text;
NSMutableString *reversedString = [NSMutableString string];
NSInteger charIndex = [myString length];
while (myString && charIndex > 0) {
    charIndex--;
    NSRange subStrRange = NSMakeRange(charIndex, 1);
    [reversedString appendString:[myString substringWithRange:subStrRange]];
}

Scale to fill for UIColor pattern UIImage

Sometimes we need to scale to fill our images to fit in certain image view. This code snippet easly do this. I definitely recommend to you use UIImage category for this. So that you don’t repeat same code again and again.

 
+ (UIImage *)fitImageWithView:(UIView *)view imageName:(NSString *)imageName {
    
    if(imageName.length < 1) {
        [NSException raise:@"There is no image name." format:@"Image name is : %@", imageName];
    }
    
    UIImage *img = nil;
    
    UIGraphicsBeginImageContext(view.frame.size);
    [[UIImage imageNamed:imageName] drawInRect:view.bounds];
    img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return img;
}

Quick tip: Import necessary classes in a single file

When we working on a project and it has lot of class where doing same job we don’t need to import these classes again and again. Instead we need to a model class. Declare these classes in a single model class and use this class when necessary.

UserModel.h – Implementation file

#import "UserInformation.h"
#import "UserProducts.h"
#import "UserFriendList.h"

After that we should declare this model in our “Prefix” file.

#ifdef __OBJC__
     #import "UserModel.h"
#endif

Public functions

In Objective-C some APIs may wish to  expose own helper functions publicly. For concern and state procedures. Functions are great way to encapsulate like these behaviours. If you think they’re really useful, it may be worth making them available globally.

Interface File:

typedef NS_ENUM(NSUInteger, UserState) {
    UserState_Active,
    UserState_Deactive,
    UserState_SuperUser,
    UserState_Admin,
    UserState_Moderator
};

extern NSString *NSStringFromUserState(UserState state);

Implematation File

NSString *NSStringFromUserState(UserState state) {
    
    switch (state) {
        case UserState_Admin: return @"Admin";
        case UserState_Moderator: return @"Moderator";
        case UserState_SuperUser: return @"Super User";
        case UserState_Active: return @"Active User";
        case UserState_Deactive: return @"De-active User";
        default:return nil;
    }
    return nil;
}

iOS Check if string empty?

Evet kısa bir code-snippet paylaşacağım. Daha sonra bunun üzerine bir kaç bir şey daha ekleyeceğim. Şimdi yeni öğrendiğim ve bu konu üzerine geçmiş soru işaretlerim olduğu için daha detaylı bir arama ile blog yazısı paylaşacağım. Ama aşağıdaki kod basit olarak bir NSString değerinin boş olup olmadığını kontrol ediyor. Bunun için bir macro yapılabilir.

#define allTrim( object ) [object stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ]

Daha sonra kodda bunu kontrol edebilmek için;

NSString *emptyString = @"   ";

if ( [allTrim( emptyString ) length] == 0 ) NSLog(@"Is empty!");

Kod iki şekilde de çalışabilir isterseniz @”” şekilde de deneyebilirsiniz.

Ayrıca aşağıdaki kaynakları da kontrol edebilirsiniz.

http://blog.wilshipley.com/2005/10/pimp-my-code-interlude-free-code.html

http://stackoverflow.com/questions/899209/how-do-i-test-if-a-string-is-empty-in-objective-c

iOS Block-code with Property

Yeni yıla girdik malum. Benim normalde de tüm yılım bilgisayar başında geçtiği için yeni yıla da bilgisayarım ile kod yazarak girdim 🙂 Pişman mıyım. Tabii amsterdam’da yılbaşı kutlamak ya da başka bir yerde çılgınca eğlenip yılbaşı kutlamak daha cazip geliyor. Ancak kendi koyduğum hedefler doğrultusunda çok çalışmam gerek. Şimdiden kendime 2015 yılı öğrenme takvimi gibi bir şey hazırladım 🙂

Neyse konuya gelelim. Block-code Objectvice-C’de en çok kullandığım özelliklerden birisi. Çok severim. Hem kullanırlığı kolay hem OO(Object Oriented) yapısına oldukça musait. Şimdi;

Interface dosyamızın hemen üstüne bir type-definition yani typedef oluşturuyoruz;

typedef void(^DoSomething)(void);

Daha sonra interface dosyamızda property olarak tanımlayabiliriz.

@property (nonatomic, copy) DoSomething somethingBlock;

Implementasyon dosyamızda “.m” istediğimiz işlemleri gerçekleştirebiliyoruz. Ben sadece NSLog ile bir şeyler yazdırdım. Tabii objemizin instantie edilmiş olması gerekiyor.


SomeClass *class = [[self alloc] init];

class.somethingBlock = ^{
        NSLog(@"Hello new year!!");
    };

Şimdi kullanmak istediğimiz sınıfımdızda dot syntax yaparak kullanbiliriz.


SomeClass *class = [[SomeClass alloc] init];
class.somethingBlock();

iOS TextView Prefix

Yaptığımız projelerin bazı noktalarında text girdilerine ön ek “prefix” koymak isteyebiliriz. Bu telefon kodu olabilir, “Sayın” gibi ifadeler de kullanabiliriz. Kullandığımız bu ön eklerin silinmemesi için “UITextField” sınıfının “UITextViewDelegate” delege methodlarından olan “textView:shouldChangeTextInRange:replacementText” methodunu kullanarak yapabiliriz.

Yapmamız gereken ilk olarak önceki metin ile sonraki metinleri birleştirmek. Daha sonra bu birleşimi bir NSString değişkeni içerisinde tutup daha sonra if-else koşulu ile eklediğimiz ön ek metin değerin uzunluğunu kontrol edip eğer birleştirilen metin belirtiğimiz ön ek metinin uzunluğundan küçük ise ön ekimizin silinmesini engelliyoruz. Bunu aşağıdaki kod ile yapabilirsiniz;

Prefix “Ön Ek” değerimiz

static NSString *const PREFIX_TEXT = @"Merhaba, ";

TextView’ımıza ekleceğimiz ön eki giriyoruz.

myTextView.text = PREFIX_TEXT;

Daha sonra delege metodumuzla kontrolleri sağlıyoruz.



- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    
    // Eski text değeriyle yenisini birleştiriyoruz...
    NSString *combinedText = [textView.text stringByReplacingCharactersInRange:range withString:text];
    
    // Eğer kullanıcı 4. karakterlerden sonraki karakterleri silmek istiyorsa bir prefix oluşturuyoruz
    // daha sonra text'in başına ön ek koyuyoruz.
    if(combinedText.length < 4) {
        textView.text = PREFIX_TEXT;
        return NO;
    }
    else if(![[textView.text substringToIndex:4] isEqualToString:[combinedText substringToIndex:4]]) {
        return NO;
    }
    
    return YES;
    
}

iOS Table Empty View

Listeleme gerektiren ya da ekleme – çıkarma yaptığımız Table View bölümlerinde eğer listelenecek herhangi bir içerik olmadığını göstermek istiyorsak iki yolu var. Birisi Alert View kullanmak ikincisi de table view’a direk mesaj yazmak. İkincisi her zaman terciğim. Ancak genelde table listesinin hücresine(cell) yazmayı tercih ediyordum. Bu da bir çok gereksiz koşul koymamı sağlıyordu. Bugün daha güzelini keşfettim. Table listesinin üzerine başka bir view eklemek ve dolu-boş koşuna göre göster-gizle yapmak. Kulağa mantıklı geliyor değil mi ? Yani “Talk is cheap show me your code.” diyenlerdenseniz aşağıya göz atabilirsiniz.
viewDidLoad:


- (void)viewDidLoad {
    [super viewDidLoad];

    // Global declared 'noMatchedView'
    noMatchedView = [[UIView alloc] initWithFrame:self.view.frame];
    noMatchedView.backgroundColor = [UIColor whiteColor];
    
    noMatchedLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
    noMatchedLabel.font = [UIFont boldSystemFontOfSize:18];
    noMatchedLabel.numberOfLines = 1;
    noMatchedLabel.shadowColor = [UIColor lightTextColor];
    noMatchedLabel.textColor = [UIColor darkGrayColor];
    noMatchedLabel.shadowOffset = CGSizeMake(0, 1);
    noMatchedLabel.backgroundColor = [UIColor clearColor];
    noMatchedLabel.text = @"Takas edeceğiniz ürününüz yok.";
    noMatchedLabel.textAlignment = NSTextAlignmentCenter;
    noMatchedView.hidden = YES;
    [noMatchedView addSubview:noMatchedLabel];
    [self.tableView insertSubview:noMatchedView belowSubview:self.tableView];
}

daha sonra tableView:numberOfRowsInSection delegate metodunda göster-gizle işlemini yapabiliriz.


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    if(self.items.count == 0) {
        self.tableView.separatorColor = [UIColor clearColor];
        noMatchedView.hidden = NO;
    } else {
        noMatchedView.hidden = YES;
    }
    return self.items.count;
}

Ayrıca aşağıdaki hazır ve gayet güzel olan TableView / CollectionView ile uyumlu bir kütüphane var.
https://github.com/dzenbot/DZNEmptyDataSet

iOS Call dynamic class

iOS projelerinde sıkça table view controller yapılarını kullanırız. Bu yapı geliştiriciye bir çok yeniliği getirdiği gibi aynı zaman da geliştirme sürecini de önemli ölçüde azaltığını düşünüyorum. Bu yazımda da bahsetmek istediğim şey dinamik olarak projemizin package’ında bununan herhangi bir sınıfı tableview’in cell’inin herhangi birine tıkladığında çağırılmasını işleyeceğiz. Örneğin kullanıcı 1. indexe sahip cell’e tıklarsa Class1.m sınıfını çağırmayı göstermeye çalışacağım.

TableViewController’ı oluşturduğunuzu ve tableView:didSelectRowAtIndexPath:indexPath metodunun içerisine aşağıdaki kodu yazalım;


NSString *viewControllerClassName = [NSString stringWithFormat:@"Class%@ViewController", @(indexPath.row + 1)];
Class viewControllerKlass = NSClassFromString(viewControllerClassName);
NSAssert(viewControllerKlass, @"Sınıf tanımsız olmamalı!");
NSAssert([viewControllerKlass isSubclassOfClass:[UIViewController class]], @"Tanımladığınız sınıf UIViewController sınıfına ait olmalı!");

UIViewController *demoViewController = [[viewControllerKlass alloc] initWithNibName:nil bundle:nil];

// belirtilen sınıf package da varsa navigationcontroller'a push et.
if (demoViewController) {
       [self.navigationController pushViewController:demoViewController animated:YES];
}

TableViewController’ımız da 4 adet cell olduğunu varsayarak sınıflarımız sırasıyla ;

Class1ViewController.m
Class2ViewController.m

şeklinde olmalıdır.