Translate

2013年3月30日 星期六

舊專案不能選模擬器出現My Mac 64-bit

最近在整理電腦裡的專案發現有些舊專案不能跑
也不能選擇模擬器
只有My Mac 64-bit 可以執行
但是按了Run一樣沒反應
這時候只要點專案的PROJECT->Build Settings->Base SDK這邊修改為Xcode有的SDK
這時候再去Run大致上都可以執行了

2013年3月29日 星期五

NSDateFormatter格式化的資料

參考1

參考2

與時間相關
參數 代表意義

a AM/PM (上午/下午)
K 0~11 有0時的12小時制
h 1~12 12小時制
H 0~23 有0時的24小时制
k 1~24 24小時制
m 0~59 分鐘
s 0~59 秒數
s 秒數的個位數
A 0~86399999 一天當中的第幾微秒

v~vvv 一般的GMT時區縮寫
vvvv 一般的GMT時區名稱
z~zzz 具體的GMT時區縮寫
zzzz 具體的GMT時區名稱

與日期相關
參數 代表意義

d 1~31 日期
D 1~366 一年的第幾天
e 1~7 一週的第幾天
c/cc 1~7 一週的第幾天,星期日為第一天

ccc 星期幾縮寫
E~EEE 星期幾縮寫
cccc 星期幾全名
EEEE 星期幾全名

F 1~5 每月第幾周,一周的第一天為周一
w 1~5 每月第幾周,一周的第一天為周日
w 1~53 一年的第幾周,從去年的最後一個周日算起,一周的第一天為周日

L/LL 1~12 第幾個月
M/MM 1~12 第幾個月
LLL 月份縮寫
MMM 月份縮寫
LLLL 月份全名
MMMM 月份全名

q/qq 1~4 第幾季
Q/QQ 1~4 第幾季
qqq 季度縮寫
QQQ 季度縮寫
qqqq 季度全名
QQQQ 季度全名

u 完整年份
y/yyyy 完整年份
Y/YYYY 完整年份,從星期天開始的第一周算起
yy/yyy 兩位數的年份
YY/YYY 兩位數的年份,從星期天開始的第一周算起

特殊用途
參數 代表意義

g Julian Day Number,從4713 BC一月一日算起
G~GGG BC/AD 西元前後縮寫
GGGG 西元前後全名

這裡只有列出幾個常用常用參數,還有一些小技巧並沒有詳述,例如今天是 15 號,輸入參數 d 或是 dd 皆可以得到數值 15,可是輸入 ddd 卻會得到數值 015,而輸入 dddd 又會得到 0015,其他的參數也可以此類推,有興趣的讀者們可以自行實驗。

2013年3月28日 星期四

取得照片拍照时间跟地理位置信息

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
if(picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary){
//UIImage *image= [info objectForKey:UIImagePickerControllerOriginalImage];

NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL]; 
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:assetURL
resultBlock:^(ALAsset *asset) {
NSDictionary* imageMetadata = [[NSMutableDictionary alloc] initWithDictionary:asset.defaultRepresentation.metadata]; 
NSDictionary *GPSDict=[imageMetadata objectForKey:(NSString*)kCGImagePropertyGPSDictionary];
NSLog(@"%@",GPSDict);
NSLog(@"%@",imageMetadata);
/* GPSDict 里面即是照片的GPS信息,具体可以输出看看*/
}
failureBlock:^(NSError *error) {
}];
} 
}

怎么自定义 视频播放的声音 和 进度条

參考1 
參考2 
參考3 
參考4 

//注册一个通知来观察状态
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackStateDidChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:[playerViewController moviePlayer]];


- (void)playbackStateDidChange:(NSNotification *)aNote
{
MPMoviePlayerController *moviePlayer = [aNote object];


switch (moviePlayer.playbackState) {
case MPMoviePlaybackStateStopped:
break;
case MPMoviePlaybackStatePlaying:

break;
case MPMoviePlaybackStatePaused:

break;
case MPMoviePlaybackStateInterrupted:

break;
case MPMoviePlaybackStateSeekingForward:

break;
case MPMoviePlaybackStateSeekingBackward:

break;
default:
break;
}



CGFloat playtime = [moviePlayer currentPlaybackTime];//当前时间

}

MKPolyline

stackoverflow
捕获MKMapview的touch事件

2013年3月26日 星期二

Custom UITableViewCell setSelectedBackgroundView

在專案又用到客制化的select時的特效改變
上網查了一下原來不難
最簡單的方法為
cell.selectionStyle = UITableViewCellSelectionStyleGray;

但是這跟我要的顏色不同
所以呢又發現到有這樣的寫法
UIView *bgColorView = [[UIView alloc] init]; [bgColorView setBackgroundColor:[UIColor redColor]]; [cell setSelectedBackgroundView:bgColorView];
如果你的Custom UITableViewCell 使用在groupe樣板
Don't forget to import QuartzCore.
UIView *bgColorView = [[UIView alloc] init]; [bgColorView setBackgroundColor:[UIColor redColor]]; bgColorView.layer.cornerRadius = 10; [cell setSelectedBackgroundView:bgColorView]; [bgColorView release];
另外一種是我沒試過的
在Custom UITableViewCell的.m檔裡作修改
- (void)setSelected:(BOOL)selected animated:(BOOL)animated { UIImage *selectionBackground = [UIImage imageNamed:@"yellow_bar.png"]; UIImageView *iview=[[UIImageView alloc] initWithImage:selectionBackground]; self.selectedBackgroundView=iview; }

2013年3月18日 星期一

AVAudioPlayer AVAudioPlayer Volume too low

本來寫好的AVAudioPlayer跟AVAudioPlayer
卻被抓到bug真是悲傷啊
原來是PM發現錄音的時候播放聲音很正常
可是呢在音效列表播放跟拍照時播放時候
聲音卻非常的小聲
上網查了資料
參考鏈結
Oh! Not!
改得這麼複雜有沒有簡單一點的!
後來我自己回去本來的專案看發現
我有在播放的時候寫了幾行代碼可以讓聲音的音量很正常
所以我就把那幾行代碼全都複製到音效列表跟拍照頁面那
果不其然音量正常了真是太好了
果然是魔鬼就藏在細節當中
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride); player.volume = 1.0; [player play];

Singleton sharedInstance

這次在公司的專案有用到Singleton
當然不是我自己想用的拉
是上網找的範例模組有用到只好強迫自己知道這到底有什麼作用
上網找了許多資料有許多人的講法都不一定相同
但是有找到一個我個人覺得算是講得很詳細的

這是為什麼要這樣用
這個 Design Pattern 是用來確保程式中某些物件實體只能有一個、或是數個,不應該被重複性的建立

介紹參考
iOS 单例模式
怎樣用呢
最近在iOS开发中,需要用到单例模式,于是自己动手写了一个,它看起来是这样的:
1.
+ (id)sharedInstance { static id sharedInstance = nil; if (!sharedInstance) { sharedInstance = [[NSObject alloc] init]; } return sharedInstance; }
后来发现许多书上的做法都使用到了BOOL变量作为标值位,它看起来是这样的:
2.
+ (id)sharedInstance { static id sharedInstance = nil; static BOOL token = NO; if (!token) { token = YES; sharedInstance = [[NSObject alloc] init]; } return sharedInstance; } 但是参考了苹果官方的单例模式代码,发现它看起来是这样的:
3.
+ (id)sharedInstance { static id sharedInstance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[NSObject alloc] init]; }); return sharedInstance; } 那么它们究竟有多大区别呢?
原来,它们的区别在于多线程并发时的表现。

使用了一个指针变量作为标志位,这在多线程并发时是不可取的,因为sharedInstance = [[NSObject alloc] init];这行代码的执行本身是需要时间的。很可能有两个线程同时进入到了这行代码,而这将导致内存泄漏。

使用的标志位是一个BOOL变量,当多线程并发时,会出现1线程判断为NO,开始alloc并做赋值操作,但是2线程进入时判断为YES,而1线程赋值操作还没执行结束,这时候2线程会拿到一个nil。尽管它不会造成内存泄漏,但是它会有相当多的线程获取不到对象。

使用了dispatch_once函数。这个函数来自于Grand Central Dispatch (GCD),Apple自Mac OS 10.6 / iOS 4.0引用了它。
该函数接收一个dispatch_once_t用于检查该代码块是否已经被调度的谓词(是一个长整型,实际上作为BOOL使用)。它还接收一个希望在应用的生命周期内仅被调度一次的代码块。这不仅意味着代码仅会被运行一次,而且还是线程安全的,你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。

Apple的GCD Documentation证实了这一点:
如果被多个线程调用,该函数会同步等等直至代码块完成。

所以我又上google查看看其他說法
目前我覺得這是最多人覺得這答案最好

+(id)sharedInstance { static dispatch_once_t pred; static MyClass *sharedInstance = nil; dispatch_once(&pred, ^{ sharedInstance = [[MyClass alloc] init]; }); return sharedInstance; }
釋放掉
- (void)dealloc { // implement -dealloc & remove abort() when refactoring for // non-singleton use. abort(); }
參考
+ (MyClass *)sharedInstance { static MyClass *sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[MyClass alloc] init]; // Do any other initialisation stuff here }); return sharedInstance; }
不建議這樣寫
+ (MyClass *)sharedInstance { static MyClass *sharedInstance = nil; @synchronized(self) { if (sharedInstance == nil) { sharedInstance = [[self alloc] init]; } } return sharedInstance; }

2013年3月14日 星期四

Incompatible pointer type initializing 'CustomCellView *' with an expression of type UITableViewCell

雖然我不是個完美主義者
但是看到錯誤訊息還是想要把問題解決
Incompatible pointer type initializing 'CustomCellView *' with an expression of type UItableViewCell
上網查了一下
很多都是回應關於
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

static NSString *CellIdentifier = @"CustomCell";
CustomCellView *cell =(CustomCellView*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

但是我的問題是卡在
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

本來寫法為
NewsCell *cell = [tableView cellForRowAtIndexPath:indexPath];

改為
NewsCell *cell = (NewsCell*)[tableView cellForRowAtIndexPath:indexPath];
就好了

iOS本地通知和远程通知

參考CocoaChina的文章
iOS本地通知和远程通知

值得好好看的文件解釋的很棒

APNS的推送通知

剛好在找UIAlertView的時候看到這篇文章
樓主發問說如何發佈像這樣APNS裡面還有可愛的圖示
在我之前做過的專案裡面也有用到push notification
所以我也很好奇是如何辦到的
像左圖

原來是用了Emoji圖示字串
Emoji Alerts

stretchableImageWithLeftCapWidth:topCapHeight:

為了要客制化UIAlertView上網查了很多別人已經寫好的程式碼
老是看到這個方法
stretchableImageWithLeftCapWidth:topCapHeight:
很好奇這到底是用來幹嘛的
原來這方法上網看了別人的解釋是這樣的
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight

这个函数是UIImage的一个实例函数,它的功能是创建一个内容可拉伸,而边角不拉伸的图片,需要两个参数,第一个是不拉伸区域和左边框的宽度,第二个参数是不拉伸区域和上边框的宽度。

第一次用这个函数的时候一直搞不懂为什么只要两个参数就行,至少应该指定左上角和右下角,总共四个参数啊。后来读读文档才明白,只需要两个参数就行了。

参数的意义是,如果参数指定10,5。那么,图片左边10个像素,上边5个像素。不会被拉伸,x坐标为11和一个像素会被横向复制,y坐标为6的一个像素会被纵向复制。注意:只是对一个像素进行复制到一定宽度。

其实就是对一个图像做处理,只将中间需要放大的部分进行缩放,而四个角不做拉伸,四个边只做单方向上的拉伸。这种技术通常用于创建可变宽度按钮,包邮相同圆角,但其中心区域的放大和缩小的需要

用该函数设置UIButton的image时, 只对backgroundImage启作用

参数
leftCapWidth
要使用的值上限为左侧的宽度。指定0如果你不希望的形象是横向拉伸。
topCapHeight
要使用的值为顶盖的宽度。指定0如果你不希望的形象是垂直拉伸。

但是在iOS5.0以後就不能用這方法了囧
可以在iOS6.1也沒有報錯.我想應該還是可以繼續使用吧!

參考鏈結裡有更詳細的解釋我覺得很棒
stretchableImageWithLeftCapWidth:topCapHeight:函数用法

2013年3月13日 星期三

NSFileManager creat Folder

最近需要自己創個資料夾
放在app裡的document的資料夾裡面
上網查了資料
發現要使用NSFileManager來創資料夾
通常使用NSFileManager有兩種
NSFileManager* fileMag = [[NSFileManager alloc] init];
或直接使用
[NSFileManager defaultManager]

以下是直接使用[NSFileManager defaultManager]

NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsPath = [paths objectAtIndex:0]; NSString *fileFolder = [documentsPath stringByAppendingPathComponent:@"myRecord"]; // 如果資料夾不存在 if (![[NSFileManager defaultManager] fileExistsAtPath:fileFolder]){ NSError* error; if([[NSFileManager defaultManager] createDirectoryAtPath:fileFolder withIntermediateDirectories:YES attributes:nil error:&error]) { NSLog(@"success"); } else { NSLog(@"[%@] ERROR: attempting to write create MyFolder directory", [self class]); NSAssert( FALSE, @"Failed to create directory maybe out of disk space?"); } } else { // 資料夾存在 } 

主要使用到creat資料夾是用
NSError* error; [[NSFileManager defaultManager] createDirectoryAtPath:fileFolder withIntermediateDirectories:YES attributes:nil error:&error] 

NSMutableDictionary setValue forKey crash

在某次我需要利用相同NSMutableDictionary來做key值的改變
並替換掉原本的NSMutableDictionary卻發現會crash
本來的寫法是
//list_data是陣列裡面包的是NSMutableDictionary
NSMutableDictionary *tag_dic = [list_data objectAtIndex:row];

[tag_dic setValue:[NSString stringWithFormat:@"%d",index_sound + 1] forKey:@"sound_order"];

就這樣crash掉了 囧 too bad!
後來上網找 發現只要這樣寫就可以了
NSMutableDictionary *tag_dic = [[list_data objectAtIndex:row] mutableCopy];

 [tag_dic setValue:[NSString stringWithFormat:@"%d",index_sound + 1] forKey:@"sound_order"]; 真是太神奇了傑克!

2013年3月11日 星期一

NSUserDefaults

引用
http://gibuloto.com/blog/nsuserdefaults/

重點是
在設定完之後記得要
[[NSUserDefaults standardUserDefaults] synchronize];

NSUserDefaults 可以用來儲存使用者的偏好設定(它會被存成一個 .plist 檔案),你可以把它想成是 iOS app 的 localStorage,而且 NSUserDefaults 不只可以儲存字串,還可以儲存任何 Objective-C data type。

使用方法


// 你得先宣告一個 NSUserDefaults 物件,在同一個 app 裡,它是 singleton(單例) NSUserDefaults *userPrefs = [NSUserDefaults standardUserDefaults]; // set [userPrefs setObject:@"a123456789" forKey:@"userID"]; [userPrefs setInteger:24 forKey:@"age"]; [userPrefs setBool:YES forKey:@"isLogin"]; // remove [userPrefs removeObjectForKey:@"debts"]; [userPrefs synchronize]; // get NSString *userID = [userPrefs stringForKey:@"userID"]; BOOL isLogin = [userPrefs boolForKey:@"isLogin"]; 

要注意的是,set 或 remove 之後,記得執行 [userPrefs synchronize],已確保資料被寫入硬碟裡。再保險一點,你還可以:

  - (void)applicationWillEnterForeground:(UIApplication *)application { /* Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. */ [[NSUserDefaults standardUserDefaults] synchronize]; }

2013年3月7日 星期四

FMDB ld: 1 duplicate symbol for architecture armv7s

今天第一次使用FMDB之前都是用舊公司的DB讀取資料
一開始先加入
libsqlite3.0.dylib的資料庫
再加入FMDB的src
FMDatabase.h
FMDatabase.m
FMDatabaseAdditions.h
FMDatabaseAdditions.m
fmdb.m
FMResultSet.h
FMResultSet.m
沒想到在compile的時候報錯
訊息為
duplicate symbol _main in:
    /Users/apple/Library/Developer/Xcode/DerivedData/DogCam-cvhwautedscftlgteittuievolks/Build/Intermediates/DogCam.build/Debug-iphoneos/DogCam.build/Objects-normal/armv7s/main.o
    /Users/apple/Library/Developer/Xcode/DerivedData/DogCam-cvhwautedscftlgteittuievolks/Build/Intermediates/DogCam.build/Debug-iphoneos/DogCam.build/Objects-normal/armv7s/fmdb.o
ld: 1 duplicate symbol for architecture armv7s
clang: error: linker command failed with exit code 1 (use -v to see invocation)

後來發現只要移除fmdb.m檔就好了
然後引用標題檔
#import "FMDatabase.h"

AVAudioPlayer play mp3 and replay

use
AVAudioPlayer need add AVFoundation.framework!

and
 #import <AVFoundation/AVFoundation.h>
AVAudioPlayer Notification issue: delegate- audioPlayerDidFinishPlaying:successfully

AVAudioPlayer *player;

播放mp3



NSString *fileName = @"test"; NSURL *url = [[NSURL alloc] initFileURLWithPath: [[NSBundle mainBundle] pathForResource:fileName ofType:@"mp3"] isDirectory:NO]; NSError* error = nil; player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error]; player.delegate = self; if (!url || error) { } player.volume = 1; player.numberOfLoops = -1;// -1 = repeat forever [player prepareToPlay]; [player play]; pause if([player isPlaying]) { [player pause]; player = nil; } #pragma mark - #pragma mark AVAudioPlayer delegate - (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *)aPlayer successfully: (BOOL)flag { if (flag == YES) { NSLog(@"audioPlayerDidFinishPlaying"); } }

DMCircularScrollView Crash

在新公司用需要用到一各比較特別的UI
上網查了查發現這個很適合專案要的感覺
沒想到用了四五個小時卻一直當掉
找不出原因
只好把整個網址上網google沒想到


真的是太蝦了拉  
原來要ARC的專案
可是我的專案沒有支援ARC
上網找了一下發現在
[iOS筆記]部份檔案使用/不使用ARC
借我引用一下重點
在專案的TARGETS->Bulid Phases->Compile Sources
選擇不要的.m在Compile Flags設定-fobjc-arc
搞定可以運行了


引用一下
1. 你的專案使用 ARC, 但希望部份檔案不使用,則使用 -fno-objc-arc。
2. 如果你的專案不使用 ARC, 但部份檔案使用,則用 -fobjc-arc。













os x10.8 找不到Library資料夾

原來發現是被系統所隱藏了起來
在終端機上
chflags nohidden ~/Library/

如果想要在隱藏起來就輸入
chflags hidden ~/Library/