I am trying to get the ALAssetsGroup "camera roll" when self.assetsGroup is nil.
My problem is that it is async, and I am trying to figure out how I could do this sync...if its possible.
- (void)viewDidLoad
{
[super viewDidLoad];
if (!self.assetsLibrary) {
_assetsLibrary = [[ALAssetsLibrary alloc] init];
}
if (!self.assetsGroups) {
_assetsGroups = [[NSMutableArray alloc] init];
} else {
[self.assetsGroups removeAllObjects];
}
ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) {
ALAssetsFilter *onlyPhotosFilter = [ALAssetsFilter allPhotos];
[group setAssetsFilter:onlyPhotosFilter];
if ([group numberOfAssets] > 0)
{
[self.assetsGroups addObject:group];
} else {
[self.collectionView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
};
// enumerate only photos
NSUInteger groupTypes = ALAssetsGroupAlbum | ALAssetsGroupEvent | ALAssetsGroupFaces | ALAssetsGroupSavedPhotos;
[self.assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:listGroupBlock failureBlock:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!self.assetsGroup) {
__block ALAssetsGroup *cameraRollGroup = nil;
NSUInteger groupTypes = ALAssetsGroupAlbum | ALAssetsGroupEvent | ALAssetsGroupFaces | ALAssetsGroupSavedPhotos;
[self.assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
// Set to Camera Roll
if ([[group valueForProperty:#"ALAssetsGroupPropertyType"] intValue] == ALAssetsGroupSavedPhotos) {
cameraRollGroup = group;
*stop = YES;
return;
}
} failureBlock:^(NSError *error) {
}];
self.assetsGroup = cameraRollGroup;
}
self.title = [self.assetsGroup valueForProperty:ALAssetsGroupPropertyName];
NSLog(#"TITLE %#", self.title); // outputs NULL
if (!self.assets) {
_assets = [[NSMutableArray alloc] init];
} else {
[self.assets removeAllObjects];
}
ALAssetsGroupEnumerationResultsBlock assetsEnumerationBock = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
[self.assets addObject:result];
} else {
[self.collectionView reloadData];
}
};
ALAssetsFilter *onlyPhotosFilter = [ALAssetsFilter allPhotos];
[self.assetsGroup setAssetsFilter:onlyPhotosFilter];
[self.assetsGroup enumerateAssetsUsingBlock:assetsEnumerationBock];
}
What I ended up doing was loading the groups before presenting the uiviewcollection controller.
- (void)presentAlbumCollection
{
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
NSUInteger groupTypes = ALAssetsGroupSavedPhotos;
[assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if ([[group valueForProperty:#"ALAssetsGroupPropertyType"] intValue] == ALAssetsGroupSavedPhotos) {
AlbumCollectionViewController *albumCollectionViewController = [[AlbumCollectionViewController alloc] initWithAssetsLibrary:assetsLibrary];
albumCollectionViewController.assetsGroup = group;
[self.view.window.rootViewController presentViewController:albumCollectionViewController animated:YES completion:nil];
}
} failureBlock:^(NSError *error) {
NSLog(#"NOT FOUND!");
}];
}
Related
I try to create an application that records video and takes images at receiving a message via sockets.
What I do not arrive to do is video recording using AVFoundation.
is that because of the fact that I use a single session ?
Here is my code :
#import "ViewController.h"
#import "Parser.h"
#import "DeviceConfig.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// z-index
_vImage.layer.zPosition = 1;
_toggle.layer.zPosition = 1;
recording = NO;
[self initNetworkCommunication];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) initNetworkCommunication {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)#"192.168.0.103", 8080, &readStream, &writeStream);
input = (__bridge NSInputStream*) readStream;
output = (__bridge NSOutputStream*) writeStream;
[input setDelegate: self];
[output setDelegate: self];
[input scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[output scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[input open];
[output open];
}
- (void) sendMessage : (NSString*) message {
NSString *response = [NSString stringWithFormat:#"iam:%#", message];
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[output write:[data bytes] maxLength:[data length]];
}
- (void) stream : (NSStream*) theStream handleEvent:(NSStreamEvent) streamEvent {
switch(streamEvent) {
case NSStreamEventOpenCompleted:
[self openCamera];
break;
case NSStreamEventHasBytesAvailable:
NSLog(#"kayn");
if(theStream == input) {
uint8_t buffer[1024];
int length;
while([input hasBytesAvailable]) {
length = [input read:buffer maxLength:sizeof(buffer)];
if(length > 0) {
NSString* outputString = [[NSString alloc] initWithBytes:buffer length:length encoding:NSASCIIStringEncoding];
// To split different messages sended in buffer via Socket (in one message)
NSArray *options = [[outputString substringToIndex:[outputString length] - 1] componentsSeparatedByString:#":"];
NSLog(#"%#", options);
if(outputString != nil) {
if([options[1] isEqualToString:#"TAKE_PIC"]) {
[self takePic];
}else if([options[1] isEqualToString:#"PARAMS"]) {
Parser* parser = [[Parser alloc] initWithXMLData: options[2]];
[self changeCameraConfig:[parser getCameraOptions]];
}else if([options[1] isEqualToString:#"REC_VIDEO"]) {
[self recordVideo];
}else{
[self showMessage:#"Unknow order, please contact the administrator."];
}
}
}
}
}
break;
default:
NSLog(#"Unknown event");
}
}
- (void) showMessage : (NSString*) msg {
UIAlertView *helloWorldAlert = [[UIAlertView alloc]
initWithTitle:#"My First App" message:msg delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
// Display the Hello World Message
[helloWorldAlert show];
}
- (void) openCamera {
session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetHigh;
AVCaptureVideoPreviewLayer* previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
previewLayer.frame = self.liveCameraView.bounds;
[self.liveCameraView.layer addSublayer:previewLayer];
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
[session addInput:deviceInput];
_stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
[_stillImageOutput setOutputSettings:outputSettings];
_videoOutput = [[AVCaptureMovieFileOutput alloc] init];
[session addOutput:_videoOutput];
[session addOutput:_stillImageOutput];
[session startRunning];
}
-(void) changeCameraConfig:(NSMutableDictionary *)config {
[device lockForConfiguration:nil];
DeviceConfig* conf;
for(id key in config) {
conf = [config objectForKey:key];
//[self showMessage:#"ok"];
// Config Torch
if([key isEqualToString:#"torch"]) {
if([[conf curValue] isEqualToString: #"on"]) {
[device setTorchMode:AVCaptureTorchModeOn];
}else{
[device setTorchMode:AVCaptureTorchModeOff];
}
}
// Config Focus
if([key isEqualToString:#"focus_mode"]) {
if([[conf curValue] isEqualToString: #"auto"]) {
[device setFocusMode: AVCaptureFocusModeAutoFocus];
}else if([[conf curValue] isEqualToString: #"continous_auto"]) {
[device setFocusMode: AVCaptureFocusModeContinuousAutoFocus];
}else{
[device setFocusMode: AVCaptureFocusModeLocked];
}
}
// Config Flash
if([key isEqualToString:#"flash"]) {
if([[conf curValue] isEqualToString: #"on"]) {
[device setFlashMode: AVCaptureFlashModeOn];
}else{
[device setFlashMode:AVCaptureFlashModeOff];
}
}
// Config Exposure
if([key isEqualToString:#"white_balance"]) {
if([[conf curValue] isEqualToString: #"auto"]) {
[device setExposureMode: AVCaptureExposureModeAutoExpose];
}else if([[conf curValue] isEqualToString: #"continous_auto"]) {
[device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
}else if([[conf curValue] isEqualToString: #"custom"]) {
[device setExposureMode:AVCaptureExposureModeCustom];
}else{
[device setExposureMode:AVCaptureExposureModeLocked];
}
}
// Config White balance
if([key isEqualToString:#"exposure_mode"]) {
if([[conf curValue] isEqualToString: #"auto"]) {
[device setExposureMode: AVCaptureExposureModeAutoExpose];
}else if([[conf curValue] isEqualToString: #"continous_auto"]) {
[device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
}else if([[conf curValue] isEqualToString: #"custom"]) {
[device setExposureMode:AVCaptureExposureModeCustom];
}else{
[device setExposureMode:AVCaptureExposureModeLocked];
}
}
}
[device unlockForConfiguration];
}
-(void) takePic {
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in _stillImageOutput.connections) {
for (AVCaptureInputPort *port in [connection inputPorts]) {
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
videoConnection = connection;
break;
}
}
if (videoConnection) { break; }
}
NSLog(#"about to request a capture from: %#", _stillImageOutput);
[_stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
CFDictionaryRef exifAttachments = CMGetAttachment( imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
if (exifAttachments)
{
// Do something with the attachments.
NSLog(#"attachements: %#", exifAttachments);
}
else
NSLog(#"no attachments");
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage *image = [[UIImage alloc] initWithData:imageData];
self.vImage.image = image;
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}];
}
- (AVCaptureDevice *) CameraWithPosition:(AVCaptureDevicePosition) Position
{
NSArray *Devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *Device in Devices)
{
if ([Device position] == Position)
{
return Device;
}
}
return nil;
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)toggleCam:(id)sender {
AVCaptureDeviceInput* newDeviceInput;
NSError* error;
AVCaptureDevicePosition position = [[deviceInput device] position];
if(position == AVCaptureDevicePositionBack) {
newDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self CameraWithPosition:AVCaptureDevicePositionBack] error:&error];
}else{
newDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self CameraWithPosition:AVCaptureDevicePositionFront] error:&error];
}
if(error != nil) {
[session beginConfiguration]; //We can now change the inputs and output configuration. Use commitConfiguration to end
[session removeInput:deviceInput];
if ([session canAddInput:newDeviceInput])
{
[session addInput:newDeviceInput];
deviceInput = newDeviceInput;
}
else
{
[session addInput:deviceInput];
}
//Set the connection properties again
//[self CameraSetOutputProperties];
[session commitConfiguration];
}
}
-(void) recordVideo {
[self showMessage:#"recording .."];
// If we are not recording
if(!recording) {
recording = YES;
NSString* path = [[NSString alloc] initWithFormat:#"%#%#", NSTemporaryDirectory(), #"output_video.wav"];
NSURL* url = [[NSURL alloc] initFileURLWithPath:path];
NSFileManager* fileManager = [NSFileManager defaultManager];
if([fileManager fileExistsAtPath:path]) {
NSError* errorMsg;
if ([fileManager removeItemAtPath:path error:&errorMsg] == NO)
{
//Error - handle if requried
}
}
[_videoOutput startRecordingToOutputFileURL:url recordingDelegate:self];
}else{
recording = NO;
[_videoOutput stopRecording];
}
}
-(void) captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error {
BOOL recordedSuccessfully = YES;
if ([error code] != noErr) {
// A problem occurred: Find out if the recording was successful.
id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey];
if (value) {
recordedSuccessfully = [value boolValue];
}
}
if(recordedSuccessfully) {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if([ALAssetsLibrary authorizationStatus]) {
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputFileURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:outputFileURL
completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
}
}];
}
}else{
[self showMessage:#"Error"];
}
}
}
#end
I am making a game in which the player can achieve a positive high score or a negative low score depending on the choices they make. The high score has been working fine, but I'm having trouble with the low score.
-(void)authenticateLocalPlayer{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
if (viewController != nil) {
[self presentViewController:viewController animated:YES completion:nil];
}
else{
if ([GKLocalPlayer localPlayer].authenticated) {
_gameCenterEnabled = YES;
// Get the default leaderboard identifier.
[[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
else{
_leaderboardIdentifier = leaderboardIdentifier;
}
}];
}
else{
_gameCenterEnabled = NO;
}
}
};
}
-(void)reportScore{
GKScore *highscore = [[GKScore alloc] initWithLeaderboardIdentifier:_leaderboardIdentifier];
highscore.value = HighScoreNumber;
[GKScore reportScores:#[highscore] withCompletionHandler:^(NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}];
-(void)showLeaderboardAndAchievements:(BOOL)shouldShowLeaderboard{
GKGameCenterViewController *gcViewController = [[GKGameCenterViewController alloc] init];
gcViewController.gameCenterDelegate = self;
if (shouldShowLeaderboard) {
gcViewController.viewState = GKGameCenterViewControllerStateLeaderboards;
gcViewController.leaderboardIdentifier = _leaderboardIdentifier;
}
else{
gcViewController.viewState = GKGameCenterViewControllerStateAchievements;
}
[self presentViewController:gcViewController animated:YES completion:nil];
}
You'll notice leaderboardidentifier, it is useful for reporting scores to the default leaderboard, but when I try to get it to work for two different ones, the code shuts down.
I've tried adding this to "Report Score":
GKScore *lowscore = [[GKScore alloc] initWithLeaderboardIdentifier:_leaderboardIdentifier];
lowscore.value = LowScoreNumber;
[GKScore reportScores:#[lowscore] withCompletionHandler:^(NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}];
}
Then, I change the leaderboard identifiers to match itunesconnect, but I'm not sure how I need to change authenticateLocalPlayer and shouldShowLeaderboardandAchievements.
I have some experience with game center. I have two games on the App Store that have multiple leaderboards (Squared!! and Primes!).
Instead of having one method for each leaderboard I made one method for submitting scores. Here is that method:
-(void) submitScore:(int64_t)score Leaderboard: (NSString*)leaderboard
{
//1: Check if Game Center
// features are enabled
if (!_gameCenterFeaturesEnabled) {
return;
}
//2: Create a GKScore object
GKScore* gkScore =
[[GKScore alloc]
initWithLeaderboardIdentifier:leaderboard];
//3: Set the score value
gkScore.value = score;
//4: Send the score to Game Center
[gkScore reportScoreWithCompletionHandler:
^(NSError* error) {
[self setLastError:error];
BOOL success = (error == nil);
if ([_delegate
respondsToSelector:
#selector(onScoresSubmitted:)]) {
[_delegate onScoresSubmitted:success];
}
}];
}
When you want to submit your high scores all you have to do is add something like:
[[GCHelper sharedGameKitHelper] submitScore:myLowScore Leaderboard:TELS];
[[GCHelper sharedGameKitHelper] submitScore:myHighScore Leaderboard:TEHS];
GCHelper is the class that contains my submitScore:Leaderboard: method.
To view your leaderboards or achievements within your app try this:
- (void) presentLeaderboards {
GKGameCenterViewController* gameCenterController = [[GKGameCenterViewController alloc] init];
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
gameCenterController.gameCenterDelegate = self;
[self presentViewController:gameCenterController animated:YES completion:nil];
}
- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController*) gameCenterViewController {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void) presentAchievements {
GKGameCenterViewController* gameCenterController = [[GKGameCenterViewController alloc] init];
gameCenterController.viewState = GKGameCenterViewControllerStateAchievements;
gameCenterController.gameCenterDelegate = self;
I hope this answers your question!
I am getting above error when I run program in device and it crashes,while it works fine in simulator,I am loading images using asset library and displaying in scroll view.
Here is my code::
-
(void)usingAssets{
x=0;
y=0;
w=320;
h=460;
void (^assetEnumerator)( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != NULL) {
[app hideLoading];
[assets addObject:result];
NSLog(#"assets count: %i", assets.count);
NSString *assetType = [result valueForProperty:ALAssetPropertyType];
if ([assetType isEqualToString:ALAssetTypePhoto]) {
NSLog(#"Photo Asset");
[self success];
}
}
else {
[app hideLoading];
NSLog(#"AssetEnum: result nil or end of list");
}
};
void (^assetGroupEnumerator)( ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
}
else {
NSLog(#"GroupEnum: group nil or end of list..");
}
[assets retain];
};
ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:assetGroupEnumerator
failureBlock: ^(NSError *error) {
NSLog(#"Failure: %#", error.description);
}];
// [library release];
isVisited=YES;
}
-(void)success{
dispatch_async(dispatch_get_main_queue(), ^(void){
for(int i=0;i<[assets count];i++){
asset = [assets objectAtIndex:i];
UIImage *images = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:1.0 orientation:[[asset valueForProperty:#"ALAssetPropertyOrientation"] intValue]];
imageview =[[UIImageView alloc]init];
imageview.frame=CGRectMake(x, y, w, h);
[imageview setImage:images];
[scrollview addSubview:imageview];
x = x + w ;
}
});
}
#pragma mark:----scroll view methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGPoint scrollOffset=scrollView.contentOffset;
///at any time, it will have only 3 pages loaded- previous, current and next
if(pageno < ((int)scrollOffset.x/320))
{
//unload
if(pageno>1)[self unloadPreviousPage:pageno-2];
//load the next page
[self loadScrollViewWithPage:((int)scrollOffset.x/320)+1];
}
else if(pageno > ((int)scrollOffset.x/320))
{
//unload
if(pageno<(kNumberOfPages-2))[self unloadPreviousPage:pageno+2];
//load back the previous page
[self loadScrollViewWithPage:((int)scrollOffset.x/320)-1];
}
pageno=scrollOffset.x/320;
}
-(void)unloadPreviousPage:(int)index
{
for(int i=index*4;i<(index+1)*4;i++)
{
[[scrollview viewWithTag:i+1] removeFromSuperview];
}
}
- (void)loadScrollViewWithPage:(int)page {
if (page < 0)
return;
if (page >= kNumberOfPages)
return;
pageno=page;
pgControl.currentPage=pageno-1;
if(isVisited==NO){
[NSThread detachNewThreadSelector:#selector(usingAssets) toTarget:self withObject:nil];
assets = [[NSMutableArray alloc] init];
for (ALAsset* a in assets){
NSLog(#"Item in asset");
}
}
}
Please correct me where I am going wrong.Also I wants to load images using lazy loading as first it iterates over all images and then display in scroll view so it takes more time when there are large number of images.
Also if there is any other link then please post it.
Thanks for your response in advance.
I have two problems (in fact one - my code sucks):
My table takes a long time to load(about 5 seconds)
She is dreadfully poor
Any ideas?
My tableView methods:
// Table
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
RefreshDelegate *RefreshProtocol = [[RefreshDelegate new] autorelease];
RefreshProtocol.delegate = self;
return [[RefreshProtocol returnDataForTable] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
RefreshDelegate *RefreshProtocol = [[RefreshDelegate new] autorelease];
RefreshProtocol.delegate = self;
NSArray *curent = [self curent:section];
return [curent count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
RefreshDelegate *RefreshProtocol = [[RefreshDelegate new] autorelease];
RefreshProtocol.delegate = self;
return [[[RefreshProtocol returnDataForTable] allKeys] objectAtIndex:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
NSArray *curent = [self curent:indexPath.section];
cell.textLabel.text = [curent objectAtIndex:indexPath.row];
return cell;
}
- (NSArray*)curent:(NSInteger)index {
RefreshDelegate *RefreshProtocol = [[RefreshDelegate new] autorelease];
RefreshProtocol.delegate = self;
NSArray *keys = [[RefreshProtocol returnDataForTable] allKeys];
NSString *curentKey = [keys objectAtIndex:index];
NSArray *curent = [[RefreshProtocol returnDataForTable] objectForKey:curentKey];
return curent;
}
My RefreshProtocol methods:
#define MaxCountPair 7
-(NSDictionary *)returnDataForTable{
NSMutableArray *day_1 = [NSMutableArray arrayWithCapacity:MaxCountPair];
NSMutableArray *day_2 = [NSMutableArray arrayWithCapacity:MaxCountPair];
NSMutableArray *day_3 = [NSMutableArray arrayWithCapacity:MaxCountPair];
NSMutableArray *day_4 = [NSMutableArray arrayWithCapacity:MaxCountPair];
NSMutableArray *day_5 = [NSMutableArray arrayWithCapacity:MaxCountPair];
NSMutableArray *day_6 = [NSMutableArray arrayWithCapacity:MaxCountPair];
// Analysis db and write array today
NSArray *array = [SQLiteAccess selectManyRowsWithSQL:#"select * from schedule"];
for (int i = 0; i < [array count]; i++) {
NSDictionary *dictionary = [array objectAtIndex:i];
if ([self checkOverlapDigit:[[[NSUserDefaults standardUserDefaults] valueForKey:#"numberWeek"] objectForKey:#"numberWeek"]:[dictionary objectForKey:#"week"]] && [self checkOverlapDigit:[self subgroupToInt]:[dictionary objectForKey:#"subgroup"]]) {
if ([self checkDay:[[dictionary objectForKey:#"day"] intValue]]) {
[day_1 addObject:[dictionary objectForKey:#"subject"]];
}
else {
if ([self checkDay:[[dictionary objectForKey:#"day"] intValue] - 1]) {
[day_2 addObject:[dictionary objectForKey:#"subject"]];
}
else {
if ([self checkDay:[[dictionary objectForKey:#"day"] intValue] - 2]) {
[day_3 addObject:[dictionary objectForKey:#"subject"]];
}
else {
if ([self checkDay:[[dictionary objectForKey:#"day"] intValue] - 3]) {
[day_4 addObject:[dictionary objectForKey:#"subject"]];
}
else {
if ([self checkDay:[[dictionary objectForKey:#"day"] intValue] - 4]) {
[day_5 addObject:[dictionary objectForKey:#"subject"]];
}
else {
if ([self checkDay:[[dictionary objectForKey:#"day"] intValue] - 5]) {
[day_6 addObject:[dictionary objectForKey:#"subject"]];
}
}
}
}
}
}
}
}
NSDictionary *days = [NSDictionary dictionaryWithObjectsAndKeys:day_1, #"1", day_2, #"2", day_3, #"3", day_4, #"4", day_5, #"5", day_6, #"6", nil];
return days;
}
-(NSString *)removeAllButDigit:(NSString *)originalString{
// Remove all but digit
NSMutableString *strippedString = [NSMutableString
stringWithCapacity:originalString.length];
NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet
characterSetWithCharactersInString:#"1234"];
while ([scanner isAtEnd] == NO) {
NSString *buffer;
if ([scanner scanCharactersFromSet:numbers intoString:&buffer]) {
[strippedString appendString:buffer];
} else {
[scanner setScanLocation:([scanner scanLocation] + 1)];
}
}
return strippedString;
}
-(BOOL)checkDay:(NSInteger)day{
NSString *currentDay = nil;
switch (day) {
case 1:
currentDay = NSLocalizedString(#"_monday", nil);
break;
case 2:
currentDay = NSLocalizedString(#"_tuesday", nil);
break;
case 3:
currentDay = NSLocalizedString(#"_wednesday", nil);
break;
case 4:
currentDay = NSLocalizedString(#"_thursday", nil);
break;
case 5:
currentDay = NSLocalizedString(#"_friday", nil);
break;
case 6:
currentDay = NSLocalizedString(#"_saturday", nil);
break;
default:
break;
}
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"EEEE"];
if ([currentDay isEqualToString:[dateFormatter stringFromDate:[NSDate date]]]) {
return YES;
}
return NO;
}
-(BOOL)checkOverlapDigit:(NSString *)smallerString:(NSString *)largerString{
if ([largerString isEqualToString:#"0"]) {
return YES;
}
NSInteger intSmaller = [[self removeAllButDigit:smallerString] intValue];
NSInteger intLarger = [[self removeAllButDigit:largerString] intValue];
while (1) {
if (intLarger % 10 != 0) {
NSInteger sedimentWeek = intLarger % 10;
if (sedimentWeek == intSmaller) {
return YES;
}
intLarger /= 10;
}
else {
if (intLarger / 10 != 0) {
intLarger /= 10;
if (intLarger == intSmaller) {
return YES;
}
}
else {
return NO;
}
}
}
}
-(NSString *)subgroupToInt{
if ([[[NSUserDefaults standardUserDefaults]objectForKey:#"subgroupValue"] isEqualToString: #"subgroupValue1"]) {
return #"1";
}
else
if ([[[NSUserDefaults standardUserDefaults]objectForKey:#"subgroupValue"] isEqualToString: #"subgroupValue2"]) {
return #"2";
}
else
if ([[[NSUserDefaults standardUserDefaults]objectForKey:#"subgroupValue"] isEqualToString: #"subgroupValue3"]) {
return #"3";
}
return #"4";
}
And SQLiteAccess class: .h, .m
For starting... you can (you have) to create you object only once!! (in the constructor? In -viewDidLoad ?)
Then in the tableView delegate methods you access your (unique) object.
EDIT:
Adds a property in your class:
#property (nonatomic, strong) RefreshDelegate* refreshProtocol;
In your -viewDidLoad method add
-(void)viewDidLoad
{
[super viewDidLoad];
self.refreshProtocol = [[RefreshDelegate new] autorelease];
self.refreshProtocol.delegate = self;
}
Now:
- (NSArray*)curent:(NSInteger)index {
NSArray *keys = [[self.refreshProtocol returnDataForTable] allKeys];
NSString *curentKey = [keys objectAtIndex:index];
NSArray *curent = [[self.refreshProtocol returnDataForTable] objectForKey:curentKey];
return curent;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *curent = [self curent:section];
return [curent count];
}
... and correct the other methods...
I got a big problem with NSInvocationOperation. When I run on my iPod 4, firmware 5.0.1, it's OK. But on my iPhone 4, iOS 4.1, it crashed. This is my code:
CustomAnnotation *annotation = [[[ModelManager defaultModelManager] getAnnotationDictionaryInMemory] objectForKey:joltId];
if (annotation == nil)
annotation = [[[ModelManager defaultModelManager] getAnnotationDictionaryInMemory] annotationWithInstagramId:eID];
if (annotation == nil)
continue;
//THIS ONE CRASH ON IPHONE 4 OS 4.1
NSDictionary *param = [[NSDictionary alloc] initWithObjectsAndKeys: #"aKey", #"aValue", nil];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:annotation selector:#selector(updateAnnotation:) object:param];
[_queue addOperation:op];
[op autorelease];
updateAnnotation function was defined in CustomAnnotation class:
- (void)updateAnnotation:(id)sender {
//NSLog(#"UPDATE ANNOTATION ID: %#", self.annoID);
NSDictionary *senderDic = (NSDictionary *)sender;
UzooltAppDelegate* appDelegate = (UzooltAppDelegate*) [UIApplication sharedApplication].delegate;
if ([senderDic objectForKey:#"nb_rejolt"] != nil) {
NSInteger new_nb_rejolts = [[senderDic objectForKey:#"nb_rejolt"] intValue];
//if (new_nb_rejolts != rejolts) {
//NSLog(#"update nb rejolts: %d", new_nb_rejolts);
if (self.rejolts != new_nb_rejolts) {
self.rejolts = new_nb_rejolts;
//if (self.isGrouped)
// [self.masterAnnotation.annotationView performSelectorOnMainThread:#selector(updateAnnotationViewWithRejolts:) withObject:[NSString stringWithFormat:#"%d", rejolts] waitUntilDone:NO];
//else
if ([senderDic objectForKey:#"rejolt_fbid"] != nil) {
NSString *fbRejoltsString = [senderDic objectForKey:#"rejolt_fbid"];
self.fbRejolts = [[fbRejoltsString componentsSeparatedByString:#","] mutableCopy];
[self.fbRejolts removeLastObject];
[self updateNumberOfRejoltsFromFBFrds];
}
[self.annotationView performSelectorOnMainThread:#selector(updateAnnotationViewWithRejolts:) withObject:[NSString stringWithFormat:#"%d", rejolts] waitUntilDone:NO];
}
if (self.isGrouped) {
if (self.masterAnnotation.isShowingRadius == NO && appDelegate.uMainViewController.isInGroup == NO && ( new_nb_rejolts > self.masterAnnotation.rejolts || (new_nb_rejolts == self.masterAnnotation.rejolts && self.getAge < self.masterAnnotation.getAge))) {
[self.masterAnnotation removeFromGroupedAnnotations:self];
self.annotationView.hidden = NO;
[self.annotationView performSelectorOnMainThread:#selector(showWithAlpha:) withObject:[NSNumber numberWithFloat:annotationAlpha] waitUntilDone:NO];
[[NSNotificationCenter defaultCenter] postNotificationName:#"need_group_annotations" object:nil];
}
}
//}
}
if ([senderDic objectForKey:#"lifetime"] != nil) {
float new_lifetime = [[senderDic objectForKey:#"lifetime"] floatValue]*3600;
//NSLog(#"new lifetime: %.f", new_lifetime);
if (new_lifetime != lifetime) {
//NSLog(#"update lifetime");
self.lifetime = new_lifetime;
}
}
[self updateViewAlpha];
if ([senderDic objectForKey:#"radius"] != nil) {
float new_radius = [[senderDic objectForKey:#"radius"] floatValue];
if (new_radius != radius) {
//NSLog(#"update lifetime");
self.radius = new_radius;
}
}
/*
if ([appDelegate.uMainViewController isMaximumZoomIn])
[[self annotationView] performSelectorOnMainThread:#selector(setGroupNumberIndicatorVisible:) withObject:[NSNumber numberWithBool:YES] waitUntilDone:NO];
else
[[self annotationView] performSelectorOnMainThread:#selector(setGroupNumberIndicatorVisible:) withObject:[NSNumber numberWithBool:NO] waitUntilDone:NO];
*/
if (isSelected == YES && isShowingRadius == NO ) {
//NSLog(#"update details");
[self performSelectorOnMainThread:#selector(updateDetailsView) withObject:nil waitUntilDone:NO];
UzooltAppDelegate* appDelegate = (UzooltAppDelegate*) [UIApplication sharedApplication].delegate;
if (isGrouped == YES && appDelegate.uMainViewController.isInGroup) {
NSLog(#"grouped jolt rejolted");
[self performSelectorOnMainThread:#selector(updateInGroupAnnotationView) withObject:nil waitUntilDone:NO];
}
}
}
I don't know where it wrong? Please help me. Thanks all !!!
Try running with NSZombies enabled. It should at least give you a hint as to what object you are trying to access after it has been deallocated.
NSZombies enabled, debug information