Bug with direction JSQMessage - ios

I have a problem with direction of messages in JSQMessage.
When I write and send message all good with direction but when I restart app or else that some messages changes its direction.
Its my code
#import "ChatViewController.h"
#import <AVKit/AVKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "JSQMessagesCollectionViewFlowLayout.h"
#import "JSQMessages.h"
#import "JSQPhotoMediaItem.h"
#import "JSQLocationMediaItem.h"
#import "JSQVideoMediaItem.h"
#import "JSQMessagesMediaViewBubbleImageMasker.h"
#import "JSQMessagesAvatarImage.h"
#import "JSQMessagesAvatarImageFactory.h"
#import <JSQMessagesBubbleImage.h>
#import <JSQMessagesBubbleImageFactory.h>
#import <FirebaseDatabase/FirebaseDatabase.h>
#import <FirebaseStorage/FirebaseStorage.h>
#import <FirebaseAuth/FirebaseAuth.h>
#interface ChatViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
#property (strong, nonatomic) NSMutableArray *messages;
#property (strong, nonatomic) JSQMessagesBubbleImage *outgoingBubbleImageView;
#property (strong, nonatomic) JSQMessagesBubbleImage *incomingBubbleImageView;
#property (strong, nonatomic) FIRDatabaseReference *databaseReference;
#property (strong, nonatomic) NSString *convoId;
#end
#implementation ChatViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = self.senderDisplayName;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"backgroundChat"]];
imageView.alpha = 0.5;
self.collectionView.backgroundView = imageView;
_messages = [NSMutableArray new];
_databaseReference = [[FIRDatabase database] reference];
[self setupBubbles];
self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
NSString *receiverId = [_receiverData objectForKey:#"uId"];
NSString *receiverIdFive = [receiverId substringToIndex:5];
NSString *senderIdFive = [self.senderId substringToIndex:5];
if (senderIdFive > receiverIdFive) {
_convoId = [NSString stringWithFormat:#"%#%#", senderIdFive, receiverIdFive];
} else {
_convoId = [NSString stringWithFormat:#"%#%#", receiverIdFive, senderIdFive];
}
[self observeMessages];
}
- (IBAction)backButtonAction:(id)sender {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *viewiewController = [mainStoryboard instantiateViewControllerWithIdentifier:#"HomeView"];
[self presentViewController:viewiewController animated:true completion:nil];
}
- (id<JSQMessageData>)collectionView:(JSQMessagesCollectionView *)collectionView messageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
return _messages[indexPath.item];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _messages.count;
}
- (void)setupBubbles {
JSQMessagesBubbleImageFactory *factory = [JSQMessagesBubbleImageFactory new];
_outgoingBubbleImageView = [factory outgoingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleBlueColor]];
_incomingBubbleImageView = [factory incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleLightGrayColor]];
}
- (id<JSQMessageBubbleImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView messageBubbleImageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
JSQMessage *message = _messages[indexPath.item];
if (message.senderId == self.senderId) {
return _outgoingBubbleImageView;
} else {
return _incomingBubbleImageView;
}
}
- (id<JSQMessageAvatarImageDataSource>)collectionView:(JSQMessagesCollectionView *)collectionView avatarImageDataForItemAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}
- (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
JSQMessagesCollectionViewCell *cell = [super collectionView:collectionView cellForItemAtIndexPath:indexPath];
JSQMessage *message = _messages[indexPath.item];
if (message.senderId == self.senderId) {
cell.textView.textColor = [UIColor whiteColor];
} else {
cell.textView.textColor = [UIColor blackColor];
}
return cell;
}
- (void)collectionView:(JSQMessagesCollectionView *)collectionView didTapMessageBubbleAtIndexPath:(NSIndexPath *)indexPath {
JSQMessage *message = _messages[indexPath.row];
if (message.isMediaMessage) {
JSQVideoMediaItem *mediaItem = (JSQVideoMediaItem *)message.media;
if (mediaItem != nil) {
AVPlayer *player = [AVPlayer playerWithURL:mediaItem.fileURL];
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
playerViewController.player = player;
[self presentViewController:playerViewController animated:true completion:nil];
}
}
}
- (void)didPressSendButton:(UIButton *)button withMessageText:(NSString *)text senderId:(NSString *)senderId senderDisplayName:(NSString *)senderDisplayName date:(NSDate *)date {
FIRDatabaseReference *itemReference = [[[_databaseReference child:#"message"] child:[NSString stringWithFormat:#"%#", _convoId]] childByAutoId];
NSDictionary *messageItem = #{#"text":text, #"senderId":senderId, #"mediaType":#"TEXT"};
[itemReference setValue:messageItem];
[JSQSystemSoundPlayer jsq_playMessageSentSound];
[self finishSendingMessageAnimated:YES];
}
- (void)didPressAccessoryButton:(UIButton *)sender {
UIAlertController *sheet = [UIAlertController alertControllerWithTitle:#"Send file" message:#"Appearance media files in messages depend of your internet speed" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *image = [UIAlertAction actionWithTitle:#"Image Library" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self getMediaFrom:kUTTypeImage];
}];
UIAlertAction *video = [UIAlertAction actionWithTitle:#"Video Library" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self getMediaFrom:kUTTypeMovie];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
[sheet addAction:image];
[sheet addAction:video];
[sheet addAction:cancel];
sheet.popoverPresentationController.sourceView = self.view;
sheet.popoverPresentationController.sourceRect = CGRectMake(CGRectGetMinX(self.view.frame), CGRectGetMaxY(self.view.frame), sheet.accessibilityFrame.size.width, sheet.accessibilityFrame.size.height);
[self presentViewController:sheet animated:true completion:nil];
}
- (void)getMediaFrom:(CFStringRef)type {
UIImagePickerController *picker = [UIImagePickerController new];
picker.delegate = self;
picker.mediaTypes = #[(__bridge NSString *)type];
[self presentViewController:picker animated:true completion:nil];
}
- (void)observeMessages {
FIRDatabaseQuery *messagesQuery = [[_databaseReference child:[NSString stringWithFormat:#"message/%#", _convoId]] queryLimitedToLast:25];
[messagesQuery observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
if (snapshot.value[#"senderId"] != nil) {
NSString *ID = snapshot.value[#"senderId"];
NSString *mediaType = snapshot.value[#"mediaType"];
if ([mediaType isEqual:#"TEXT"]) {
NSString *text = snapshot.value[#"text"];
[_messages addObject:[JSQMessage messageWithSenderId:ID displayName:#"" text:text]];
} else if ([mediaType isEqual:#"PHOTO"]) {
NSString *image = snapshot.value[#"fileUrl"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:image]];
JSQPhotoMediaItem *photoItem = [[JSQPhotoMediaItem alloc] initWithImage:[UIImage imageWithData:data]];
[_messages addObject:[JSQMessage messageWithSenderId:ID displayName:#"" media:photoItem]];
} else if ([mediaType isEqual:#"VIDEO"]) {
NSString *video = snapshot.value[#"fileUrl"];
JSQVideoMediaItem *videoItem = [[JSQVideoMediaItem alloc] initWithFileURL:[NSURL URLWithString:video] isReadyToPlay:true];
[_messages addObject:[JSQMessage messageWithSenderId:ID displayName:#"" media:videoItem]];
}
[self finishReceivingMessage];
}
}];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
UIImage *image = info[UIImagePickerControllerOriginalImage];
NSURL *video = info[UIImagePickerControllerMediaURL];
if (image != nil) {
[self sendMedia:image and:nil];
} else if (video != nil) {
[self sendMedia:nil and:video];
}
[picker dismissViewControllerAnimated:true completion:nil];
[self.collectionView reloadData];
}
- (void)sendMedia:(UIImage *)image and:(NSURL *)video {
if (image != nil) {
NSString *filePath = [NSString stringWithFormat:#"%#/%f", [FIRAuth auth].currentUser, [NSDate date].timeIntervalSinceReferenceDate];
NSData *data = UIImageJPEGRepresentation(image, 0.3);
FIRStorageMetadata *metadata = [FIRStorageMetadata new];
metadata.contentType = #"image/jpg";
[[[[FIRStorage storage] reference] child:filePath] putData:data metadata:metadata completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) {
if (error != nil) {
NSLog(#"%#", error.localizedDescription);
return;
}
NSString *fileURL = [metadata downloadURLs][0].absoluteString;
FIRDatabaseReference *newMessage = [[_databaseReference child:[NSString stringWithFormat:#"message/%#", _convoId]] childByAutoId];
NSDictionary *messageItem = #{#"fileUrl":fileURL, #"senderId":self.senderId, #"mediaType":#"PHOTO"};
[newMessage setValue:messageItem];
}];
} else if (video != nil) {
NSString *filePath = [NSString stringWithFormat:#"%#/%f", [FIRAuth auth].currentUser, [NSDate date].timeIntervalSinceReferenceDate];
NSData *data = [NSData dataWithContentsOfURL:video];
FIRStorageMetadata *metadata = [FIRStorageMetadata new];
metadata.contentType = #"video/mp4";
[[[[FIRStorage storage] reference] child:filePath] putData:data metadata:metadata completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) {
if (error != nil) {
NSLog(#"%#", error.localizedDescription);
return;
}
NSString *fileURL = [metadata downloadURLs][0].absoluteString;
FIRDatabaseReference *newMessage = [[_databaseReference child:[NSString stringWithFormat:#"message/%#", _convoId]] childByAutoId];
NSDictionary *messageItem = #{#"fileUrl":fileURL, #"senderId":self.senderId, #"mediaType":#"VIDEO"};
[newMessage setValue:messageItem];
}];
}
}
#end
What wrong with my code?

Related

iOS Sqlite Database guide for beginner

I'm also beginner for iOS technology. And as per my title saying that might be this question will helpful for each new developer.
So welcome to all edit my answer and correct me OR put your own answer to improve our knowledge.
In the below Example I'm considering
1) One table name is “Student”
2) Below are fields name
- First Name
- Last Name
- Address
- Birth Date
Here we can apply manipulate operation such like “Add”, “Update”, “Delete” and “Fetch” record from the table.
UPDATE :
As per other user's answer we also can mange by CoreData too. But CoreData is faster and easier then SQLite ? If data is complex then how can we manage by CoreData?
First we need to create SQLite database and table. I’m thinking there are so many way to create database and table but most sufficient way that I’m using
1) Install Firefox and Install Add-ons
https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/
2) Create Database
- Go on Firefox -> tools -> SQLite Manager
- Top left corner choose 3rd -> New Database OR On the menu bar, choose “Database” -> New Database
- Give Database name “student” and save right place in your project.
3) Create Table
- Left side menu-> select “Tables(0)” -> Right click - Create Table OR On the menu bar, choose “Table” -> Create Table
- Give Table name “student_info” and save right place in your project.
Belo Are the code for execute manipulate operation.
#import <Foundation/Foundation.h>
#import "sqlite3.h"
#interface SQLDb : NSObject
{
sqlite3 *_database;
NSString *savedDate;
}
#property (readwrite) sqlite3* _database;
#property (nonatomic, strong) NSString *savedDate;
+(SQLDb *) initEngine;
+ (SQLDb*) database ;
+(void)releaseEngine;
- (void) executeQuery:(NSString *)query;
-(void) insertRecordInStuentTable:(NSMutableDictionary *) dicOfStudent;
-(NSMutableArray *) getRecordFrom_bannerTable;
-(void)updateNameOfStuden:(NSString *)studentName withRollNumber:(NSString *)strRollNumber;
-(void) deleteAllDataFrom_Student_Table;
And for .m file
#import "SQLDb.h"
#implementation SQLDb
////Getters / Setters
#synthesize _database, savedDate;
static SQLDb* _database = nil;
//start for initialization of database
#pragma mark - Initialization Methods -
+ (SQLDb*)database
{
if (_database == nil)
_database = [[SQLDb alloc] init];
return _database;
}
+(SQLDb *) initEngine
{
if ( !_database )
{
NSString *databaseName = #“student.sqlite";
[SQLDb createEditableCopyOfFileIfNeeded:databaseName];
sqlite3 *db = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:databaseName];
NSLog(#"DB path - %#", path);
const char* dbName = [path UTF8String];
if ( sqlite3_open(dbName,&db) != SQLITE_OK )
{
NSException* initException;
initException = [NSException exceptionWithName:#"SQL Exception" reason:#"Database Initialization Failed" userInfo:nil];
#throw initException;
}
_database = [[self allocWithZone: NULL] init] ;
_database._database = db;
}
return _database;
}
+ (void)createEditableCopyOfFileIfNeeded:(NSString *)fileName
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:fileName];
BOOL success = [fileManager fileExistsAtPath:writableDBPath];
if (success)
return;
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
NSLog(#"Database Path - %#", writableDBPath);
if (!success)
NSLog(#"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
-(void) executeQuery:(NSString *)query
{
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil) == SQLITE_OK)
{
char *selectQuery = sqlite3_mprintf([query UTF8String]);
sqlite3_free(selectQuery);
sqlite3_step(statement);
sqlite3_finalize(statement);
}
}
+(void) releaseEngine
{
sqlite3_close(_database._database);
_database._database = nil;
_database = nil;
}
//==================================
-(void) insertBannerInTable:(NSMutableDictionary *) dicOfStuent
{
int ret;
const char *sql = "INSERT INTO `student` (‘firstname’, ‘lastname’, ‘bdate’, ‘address’) VALUES (?, ?, ?, ?);";
sqlite3_stmt *insStmt = NULL;
if ( !insStmt )
if ( (ret = sqlite3_prepare_v2(_database, sql, -1, &insStmt, NULL)) != SQLITE_OK ) {
NSLog(#"Proble to insert record in student");
}
// bind values
sqlite3_bind_text(insStmt, 1, [[NSString stringWithFormat:#"%#", [dicOfStuent objectForKey:#"firstname"]] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insStmt, 2, [[NSString stringWithFormat:#"%#", [dicOfStuent objectForKey:#"lastname"]] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insStmt, 3, [[NSString stringWithFormat:#"%#", [dicOfStuent objectForKey:#"bdate"]] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insStmt, 4, [[NSString stringWithFormat:#"%#", [dicOfStuent objectForKey:#“address”]] UTF8String], -1, SQLITE_TRANSIENT);
if ((ret = sqlite3_step(insStmt)) != SQLITE_DONE) {NSLog(#"error while inserting data in 'student' table");}
sqlite3_reset(insStmt);
}
-(NSMutableArray *) getRecordFrom_StudentTable
{
NSMutableArray *listofStudent = [[NSMutableArray alloc] init];
sqlite3_stmt *statement = NULL;
NSString *query = [NSString stringWithFormat:#"SELECT * FROM bannerTable"];
if (sqlite3_prepare_v2(_database, [query UTF8String], -1, &statement, nil) == SQLITE_OK)
{
while (sqlite3_step(statement) == SQLITE_ROW)
{
//('banner_id', 'banner_image', 'banner_type', 'banner_description', 'banner_link') VALUES (?, ?, ?, ?, ?)
char *mainIDChars = (char *) sqlite3_column_text(statement, 0);
char *bnrIdChars = (char *) sqlite3_column_text(statement, 1);
char *bnrImgChars = (char *) sqlite3_column_text(statement, 2);
char *bnrTypChars = (char *) sqlite3_column_text(statement, 3);
char *bnrDesChars = (char *) sqlite3_column_text(statement, 4);
char *bnrLinkChars = (char *) sqlite3_column_text(statement, 5);
NSString *mainID = #"", *advertisement_id = #"", *advertisement_image = #"", *advertisement_type = #"", *advertisement_description = #"", *advertisement_link = #"";
if(mainIDChars != NULL)
mainID = [[NSString alloc] initWithUTF8String:mainIDChars];
if(bnrIdChars != NULL)
advertisement_id = [[NSString alloc] initWithUTF8String:bnrIdChars];
if(bnrImgChars != NULL)
advertisement_image = [[NSString alloc] initWithUTF8String:bnrImgChars];
if(bnrTypChars != NULL)
advertisement_type = [[NSString alloc] initWithUTF8String:bnrTypChars];
if(bnrDesChars != NULL)
advertisement_description = [[NSString alloc] initWithUTF8String:bnrDesChars];
if(bnrLinkChars != NULL)
advertisement_link = [[NSString alloc] initWithUTF8String:bnrLinkChars];
NSMutableDictionary *dicOfStuent = [[ NSMutableDictionary alloc] init];
[dicOfStuent setObject:mainID forKey:#"main_id"];
[dicOfStuent setObject:advertisement_id forKey:#"advertisement_id"];
[dicOfStuent setObject:advertisement_image forKey:#"advertisement_image"];
[dicOfStuent setObject:advertisement_type forKey:#"is_image_url"];
[dicOfStuent setObject:advertisement_description forKey:#"advertisement_description"];
[dicOfStuent setObject:advertisement_link forKey:#"advertisement_link"];
[listofStudent addObject:dicOfStuent];
}
sqlite3_finalize(statement);
}
return listofStudent;
}
-(void)updateNameOfStuden:(NSString *)studentName withRollNumber:(NSString *)strRollNumber
{
int ret;
const char *sql = "update user_Group_ChatList set is_online = ? where Jabber_id = ?;";
sqlite3_stmt *updtStmt = NULL;
if ( !updtStmt )
if ( (ret = sqlite3_prepare_v2(_database, sql, -1, &updtStmt, NULL)) != SQLITE_OK ) {}
// bind values
sqlite3_bind_text(updtStmt, 1, [[NSString stringWithFormat:#"%#", strProductID] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(updtStmt, 2, [strTotalProduct UTF8String], -1, SQLITE_TRANSIENT);
if ((ret = sqlite3_step(updtStmt)) != SQLITE_DONE) {NSLog(#"error while updating QTY from ProductsCart Table");}
sqlite3_reset(updtStmt);
}
-(void) deleteAllDataFrom_Student_Table
{
int ret;
const char *sql = "DELETE FROM student";
sqlite3_stmt *dltStmt = NULL;
if ( !dltStmt )
if ( (ret = sqlite3_prepare_v2(_database, sql, -1, &dltStmt, NULL)) != SQLITE_OK ) {}
if ((ret = sqlite3_step(dltStmt)) != SQLITE_DONE) {NSLog(#"Error : While Deleting Record From user_Group_ChatList Table");}
sqlite3_reset(dltStmt);
}
Above are .H and .M file that will help you to manage SQLite database.
If you are a beginner to iOS technology and want to learn local storage management then i will suggest you to go with CoreData:
Manage Local storage using Core Data
Because using core data you can interact with local database in a form of object and class.
According to your Question most of them say
Coredta is better than SQLite
When you use SQLite using Adds-on tool we need to do the below things.I explain you clearly.
My DB Name is - LoginRegistration.sqlite
My DB Table Name is - TblReg
I have Login Screen.In that I have username and password field.Below that I have Login and Register Button.
When you click register button it goes to registration page view controller where we have to register first then we have to save the data on insert the data into our SQLite db.
For implementing SQLite,first we must add and import the sqlite3.h.
DatabaseOne.h
#import <Foundation/Foundation.h>
#import <sqlite3.h>
#interface DatabaseOne : NSObject{
sqlite3 *SQLDB;
NSString *dbName;
}
+(DatabaseOne *)sharedDB;
-(id)init;
- (id)initWithName:(NSString *)dbname;
- (void)createDB:(NSString *)dbname;
- (NSString *)getDBPath;
- (void)copyDatabaseIfNeeded;
- (BOOL)executeQuery:(NSString *)query;
- (NSString*)checkForNull:(char*)colValue;
- (NSMutableArray *)executeSelectQuery:(NSString *)query;
#end
DatabaseOne.m
#import "DatabaseOne.h"
#implementation DatabaseOne
static DatabaseOne *shared = nil;
/***
Create a single GSSQL instance
***/
+(DatabaseOne *)sharedDB;
{
#synchronized([DatabaseOne class])
{
if (!shared) {
return [[self alloc] init];
}
return shared;
}
return nil;
}
-(id)init
{
shared = [super init];
return shared;
}
-(id)initWithName:(NSString *)dbname;
{
self = [super init];
if (self) {
dbName =[[NSString alloc] initWithString:dbname];
[self copyDatabaseIfNeeded];
}
return self;
}
/***
Create a DB on documents with the name you given dbname;
***/
- (void)createDB:(NSString *)dbname;
{
dbName = [[NSString alloc] initWithString:dbname];
[shared copyDatabaseIfNeeded];
}
/***
Get the DB Path of Database exists in documents folder
***/
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:dbName];
}
/***
Creates and copies the DB from Resources to documents directory
***/
- (void)copyDatabaseIfNeeded {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbName];
BOOL isResourceAvail = [fileManager fileExistsAtPath:defaultDBPath];
if (isResourceAvail == NO) {
NSLog(#"DB %# is not exists in Resource to be copied",dbName);
}else
{
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSLog(#"Copying the DB %#", defaultDBPath);
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to copy database: '%#'.", [error localizedDescription]);
}
}
}
#pragma mark - query execution
/***
Execute the query string(NSString *)
***/
-(BOOL)executeQuery:(NSString *)query;
{
BOOL done = NO;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(success) {
int sql_results = sqlite3_open([dbPath UTF8String], &SQLDB);
const char *sql = [query UTF8String];
if (sql_results == SQLITE_OK) {
if(sqlite3_exec(SQLDB, sql, nil, nil, nil) == SQLITE_OK) {
printf("Good SQL\n");
done = YES;
}
else {
NSLog(#"Bad SQL: %s -- %d", sql,sql_results);
//NSLog(#"Bad SQL:%d",sql_results);
}
}
else {
printf("DB Open FAILED\n");
NSLog(#"error code %i", sql_results);
}
sqlite3_close(SQLDB);
}
else {
printf("DB not exists in application folder\n");
}
return done;
}
/***
Executes select query and returns array of results
***/
-(NSMutableArray *)executeSelectQuery:(NSString *)query
{
NSMutableArray *results = [[NSMutableArray alloc] init];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(success) {
int sql_results = sqlite3_open([dbPath UTF8String], &SQLDB);
if (sql_results == SQLITE_OK) {
const char *sql = [query UTF8String];
sqlite3_stmt *selectStmt = nil;
if (sqlite3_prepare_v2(SQLDB, sql, -1, &selectStmt, NULL) == SQLITE_OK) {
while (sqlite3_step(selectStmt) == SQLITE_ROW) {
int columnCount = sqlite3_column_count(selectStmt);
NSMutableDictionary *row = [NSMutableDictionary dictionary];
for (int i = 0; i < columnCount; i++) {
NSString *column_name = [self checkForNull:(char *)sqlite3_column_name(selectStmt, i)];
NSString *column_value = [self checkForNull:(char *)sqlite3_column_text(selectStmt, i)];
[row setValue:column_value forKey:column_name];
}
[results addObject:row];
}
}
sqlite3_reset(selectStmt);
}
sqlite3_close(SQLDB);
}
else {
printf("DB not exists in application folder\n");
}
return results;
}
/***
Checks for a NULL value
***/
- (NSString*)checkForNull:(char*)colValue {
NSString *returnValue = #"something";
if(colValue) {
returnValue = [NSString stringWithUTF8String:colValue];
}
else {
returnValue = #"nil";
}
return(returnValue);
}
#end
Now the Modal data are
Register.h
#import <Foundation/Foundation.h>
#interface Register : NSObject
#property (nonatomic,retain) NSString *strFirstName;
#property (nonatomic,retain) NSString *strLastName;
#property (nonatomic,retain) NSString *strEmailId;
#property (nonatomic,retain) NSString *strPassword;
#property (nonatomic,retain) NSString *strMobileNo;
#property (nonatomic,retain) NSString *strMilliSeconds;
#property (nonatomic,retain) NSString *IsRegister;
-(id)init;
#end
Register.m
#import "Register.h"
#implementation Register
#synthesize strPassword = _strPassword;
#synthesize strMobileNo = _strMobileNo;
#synthesize strEmailId = _strEmailId;
#synthesize strFirstName = _strFirstName;
#synthesize strLastName = _strLastName;
#synthesize strMilliSeconds = _strMilliSeconds;
#synthesize IsRegister = _IsRegister;
-(id)init
{
self = [super init];
if (self != nil)
{
_strFirstName = [[NSString alloc]init];
_strEmailId = [[NSString alloc]init];
_strPassword = [[NSString alloc]init];
_strLastName = [[NSString alloc]init];
_strMobileNo = [[NSString alloc]init];
_strMilliSeconds = [[NSString alloc]init];
_IsRegister = [[NSString alloc]init];
}
return self;
}
#end
Here I set the intermediate for ViewController(RegisterPage)-DataBase
ViewController_DBConnection.h
#import <Foundation/Foundation.h>
#import "Register.h"
#import "DatabaseOne.h"
#interface ViewController_DBConnection : NSObject
+(void)registerDB:(Register *)registerDB;
+(NSMutableArray *)GetRegisterAccount:(NSString *) whereQuery;
+(NSMutableArray *)GetRegisterDetail;
#end
ViewController_DBConnection.m
#import "ViewController_DBConnection.h"
#implementation ViewController_DBConnection
+(void)registerDB:(Register *)registerDB
{
NSString *query = [[NSString alloc]initWithFormat:#"INSERT into TblReg(Firstname,Lastname,EmailId,Password,Mobileno,Milliseconds)values(\"%#\",\"%#\",\"%#\",\"%#\",\"%#\",\"%#\")",registerDB.strFirstName,registerDB.strLastName,registerDB.strEmailId,registerDB.strPassword,registerDB.strMobileNo,registerDB.strMilliSeconds];
BOOL Success = [[DatabaseOne sharedDB]executeQuery:query];
if(Success)
{
[[NSNotificationCenter defaultCenter]postNotificationName:#"Registration Success" object:nil];
}
}
+(void)update:(Register *)registerDB
{
NSString *query = [[NSString alloc]initWithFormat:#"update TblReg Set Firstname = '%#',Lastname = '%#',EmailId = '%#' ,Password = '%#',Mobileno = '%#' WHERE Milliseconds = '%#'",registerDB.strFirstName,registerDB.strLastName,registerDB.strEmailId,registerDB.strPassword,registerDB.strMobileNo,registerDB.strMilliSeconds];
BOOL Success = [[DatabaseOne sharedDB]executeQuery:query];
if(Success)
{
[[NSNotificationCenter defaultCenter]postNotificationName:#"Updation Success" object:nil];
}
}
+(NSMutableArray *)GetRegisterAccount:(NSString *) whereQuery
{
NSString *query=[[NSString alloc]initWithFormat:#"select * from TblReg WHERE %#;", whereQuery];
NSMutableArray *arrayData = [[DatabaseOne sharedDB]executeSelectQuery:query];
return arrayData;
}
+(NSMutableArray *)GetRegisterDetail
{
NSString *query=[[NSString alloc]initWithFormat:#"select * from Register"];
NSMutableArray *arrayData = [[DatabaseOne sharedDB]executeSelectQuery:query];
return arrayData;
}
#end
Now my Register View Controller
ViewController.h
#import <UIKit/UIKit.h>
#import "DatabaseOne.h"
#import "ViewController_DBConnection.h"
#import "Register.h"
#interface ViewController : UIViewController<UITextFieldDelegate,UITextViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>{
Register *registerDB;
}
#property (strong, nonatomic) IBOutlet UITextField *firstNameTxtFld;
#property (strong, nonatomic) IBOutlet UITextField *lastNameTextField;
#property (strong, nonatomic) IBOutlet UIImageView *imageViewData;
#property (strong, nonatomic) IBOutlet UITextField *emaiIdTextField;
#property (strong, nonatomic) IBOutlet UITextField *passwordTextField;
#property (strong, nonatomic) IBOutlet UITextField *ConfirmPasswordtextField;
#property (strong, nonatomic) IBOutlet UITextField *mobilenoTextField;
- (IBAction)actionSave:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController (){
CGFloat animatedDistance;
NSMutableArray *arrayDBGetData;
}
#end
#implementation ViewController
#synthesize firstNameTxtFld,lastNameTextField,emaiIdTextField,passwordTextField,ConfirmPasswordtextField,mobilenoTextField;
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[[DatabaseOne sharedDB] createDB:#"LoginRegistration.sqlite"];
arrayDBGetData = [[NSMutableArray alloc]init];
registerDB = [[Register alloc]init];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//pragma mark - UITextField Dlelgate method
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if (![textField isEqual:firstNameTxtFld]) {
CGRect textViewRect = [self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textViewRect.origin.y + 0.5 * textViewRect.size.height;
CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
{
heightFraction = 0.0;
}
else if (heightFraction > 1.0)
{
heightFraction = 1.0;
}
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
- (IBAction)actionSave:(id)sender{
registerDB.strFirstName = firstNameTxtFld.text;
registerDB.strLastName = lastNameTextField.text;
registerDB.strEmailId = emaiIdTextField.text;
registerDB.strPassword = passwordTextField.text;
registerDB.strMobileNo = mobilenoTextField.text;
[self getMilliSeconds];
arrayDBGetData = [ViewController_DBConnection GetRegisterAccount:[NSString stringWithFormat:#"EmailId = \"%#\"",registerDB.strEmailId]];
if([firstNameTxtFld.text length]==0||[lastNameTextField.text length]==0 || [emaiIdTextField.text length]==0 || [ConfirmPasswordtextField.text length] ==0 || [mobilenoTextField.text length]==0){
[self showAlertController:#"Error!" passMessage:#"Please Enter All Fields"];
}
else if([self emailValidation:registerDB.strEmailId] == FALSE){
[self showAlertController:#"Error!" passMessage:#"Please Enter Valid Email Address"];
}
else if(![passwordTextField.text isEqualToString:ConfirmPasswordtextField.text]){
[self showAlertController:#"Error!" passMessage:#"Please Enter matching password"];
}
else if([self checkNumeric:registerDB.strMobileNo] == FALSE){
[self showAlertController:#"Error!" passMessage:#"Please Enter Valid Mobile No"];
}
else if([arrayDBGetData count]!=0){
[self showAlertController:#"Warning !" passMessage:#"Already user have this Email Address.Try New?"];
}
else{
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"Registration Success" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(registrationSuccess:)
name:#"Registration Success"
object:nil];
[ViewController_DBConnection registerDB:registerDB];
}
}
//For Checking mail with - example#gmail.com
-(BOOL)checkValidEmail:(NSString *)checkString{
BOOL stricterFilter = NO;
NSString *stricterFilterString = #"^[A-Z0-9a-z\\._%+-]+#([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$";
NSString *laxString = #"^.+#([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$";
NSString *emailRegex = stricterFilter ? stricterFilterString : laxString;
NSPredicate *emailTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegex];
return [emailTest evaluateWithObject:checkString];
}
//For Checking mail with - ex#m.in
- (BOOL)emailValidation:(NSString *)email {
NSString *emailRegEx =
#"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
#"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
#"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")#(?:(?:[a-z0-9](?:[a-"
#"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
#"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
#"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
#"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
NSPredicate *regExPredicate = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegEx];
BOOL myStringMatchesRegEx = [regExPredicate evaluateWithObject:[email lowercaseString]];
return myStringMatchesRegEx;
}
//For checking Mobile No
- (BOOL)checkNumeric:(NSString *)textvalue {
NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithRange:NSMakeRange('0',10)] invertedSet];
NSString *trimmed = [textvalue stringByTrimmingCharactersInSet:[NSCharacterSet symbolCharacterSet]];
BOOL isNumeric = trimmed.length > 0 && [trimmed rangeOfCharacterFromSet:nonNumberSet].location == NSNotFound;
return isNumeric;
}
-(void)getMilliSeconds{
NSDate *now = [[NSDate alloc] init];
NSDateFormatter *datetimeFormatter =[[NSDateFormatter alloc]init];
[datetimeFormatter setDateFormat:#"ddMMyyyyHHmmssSS"];
registerDB.strMilliSeconds=[datetimeFormatter stringFromDate:now];
}
-(void)showAlertController:(NSString *)title passMessage:(NSString *)message{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
}
-(void)registrationSuccess:(NSNotification *)notification
{
if([[notification name] isEqualToString:#"Registration Success"]){
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Success !" message:#"Registered Successfully" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
[self.navigationController popToRootViewControllerAnimated:YES];
}];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
}
#end
Now Finally I check the login screen once I registered successfully.
RootViewController.h
#import <UIKit/UIKit.h>
#import "ViewController_DBConnection.h"
#interface RootViewController : UIViewController<UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UITextField *usernameTextField;
#property (strong, nonatomic) IBOutlet UITextField *passwordTextField;
- (IBAction)actionLogin:(id)sender;
#end
RootViewController.m
#import "RootViewController.h"
#interface RootViewController ()
{
NSMutableArray *arrayGetDBData;
CGFloat animatedDistance;
}
#end
#implementation RootViewController
#synthesize usernameTextField,passwordTextField;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[[DatabaseOne sharedDB] createDB:#"LoginRegistration.sqlite"];
arrayGetDBData = [[NSMutableArray alloc]init];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionLogin:(id)sender {
//#"Error !" message:#"Username or Password is not correct"
if([usernameTextField.text length]==0||[passwordTextField.text length]==0){
[self showAlertController:#"Error!" passMessage:#"Please Enter the missing Fields"];
}
else{
arrayGetDBData = [ViewController_DBConnection GetRegisterAccount:[NSString stringWithFormat:#"Emailid = \"%#\"",usernameTextField.text]];
if(arrayGetDBData.count==0){
[self showAlertController:#"Error!" passMessage:#"Username is not correct"];
}
else if(![passwordTextField.text isEqualToString:[[arrayGetDBData objectAtIndex:0]valueForKey:#"Password"]])
{
[self showAlertController:#"Error!" passMessage:#"Password is not correct"];
}else{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Success" message:#"Successfully Logged" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
}];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
}
}
-(void)showAlertController:(NSString *)title passMessage:(NSString *)message{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark - UITextField Delegate Methods
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.3;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
heightFraction = 0.0;
else if (heightFraction > 1.0)
heightFraction = 1.0;
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
#end
Above I checked everything very clearly.It works perfectly.
Here is my answer for updating and deleting the row from the table view
**DatabaseOne.h**
#import <Foundation/Foundation.h>
#import <sqlite3.h>
#interface DatabaseOne : NSObject{
sqlite3 *SQLDB;
NSString *dbName;
}
+(DatabaseOne *)sharedDB;
-(id)init;
- (id)initWithName:(NSString *)dbname;
- (void)createDB:(NSString *)dbname;
- (NSString *)getDBPath;
- (void)copyDatabaseIfNeeded;
- (BOOL)executeQuery:(NSString *)query;
- (NSString*)checkForNull:(char*)colValue;
- (NSMutableArray *)executeSelectQuery:(NSString *)query;
#end
DatabaseOne.m
#import "DatabaseOne.h"
#implementation DatabaseOne
static DatabaseOne *shared = nil;
/***
Create a single GSSQL instance
***/
+(DatabaseOne *)sharedDB;
{
#synchronized([DatabaseOne class])
{
if (!shared) {
return [[self alloc] init];
}
return shared;
}
return nil;
}
-(id)init
{
shared = [super init];
return shared;
}
-(id)initWithName:(NSString *)dbname;
{
self = [super init];
if (self) {
dbName =[[NSString alloc] initWithString:dbname];
[self copyDatabaseIfNeeded];
}
return self;
}
/***
Create a DB on documents with the name you given dbname;
***/
- (void)createDB:(NSString *)dbname;
{
dbName = [[NSString alloc] initWithString:dbname];
[shared copyDatabaseIfNeeded];
}
/***
Get the DB Path of Database exists in documents folder
***/
- (NSString *) getDBPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:dbName];
}
/***
Creates and copies the DB from Resources to documents directory
***/
- (void)copyDatabaseIfNeeded {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbName];
BOOL isResourceAvail = [fileManager fileExistsAtPath:defaultDBPath];
if (isResourceAvail == NO) {
NSLog(#"DB %# is not exists in Resource to be copied",dbName);
}else
{
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSLog(#"Copying the DB %#", defaultDBPath);
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to copy database: '%#'.", [error localizedDescription]);
}
}
}
#pragma mark - query execution
/***
Execute the query string(NSString *)
***/
-(BOOL)executeQuery:(NSString *)query;
{
BOOL done = NO;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(success) {
int sql_results = sqlite3_open([dbPath UTF8String], &SQLDB);
const char *sql = [query UTF8String];
if (sql_results == SQLITE_OK) {
if(sqlite3_exec(SQLDB, sql, nil, nil, nil) == SQLITE_OK) {
printf("Good SQL\n");
done = YES;
}
else {
NSLog(#"Bad SQL: %s -- %d", sql,sql_results);
//NSLog(#"Bad SQL:%d",sql_results);
}
}
else {
printf("DB Open FAILED\n");
NSLog(#"error code %i", sql_results);
}
sqlite3_close(SQLDB);
}
else {
printf("DB not exists in application folder\n");
}
return done;
}
/***
Executes select query and returns array of results
***/
-(NSMutableArray *)executeSelectQuery:(NSString *)query
{
NSMutableArray *results = [[NSMutableArray alloc] init];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(success) {
int sql_results = sqlite3_open([dbPath UTF8String], &SQLDB);
if (sql_results == SQLITE_OK) {
const char *sql = [query UTF8String];
sqlite3_stmt *selectStmt = nil;
if (sqlite3_prepare_v2(SQLDB, sql, -1, &selectStmt, NULL) == SQLITE_OK) {
while (sqlite3_step(selectStmt) == SQLITE_ROW) {
int columnCount = sqlite3_column_count(selectStmt);
NSMutableDictionary *row = [NSMutableDictionary dictionary];
for (int i = 0; i < columnCount; i++) {
NSString *column_name = [self checkForNull:(char *)sqlite3_column_name(selectStmt, i)];
NSString *column_value = [self checkForNull:(char *)sqlite3_column_text(selectStmt, i)];
[row setValue:column_value forKey:column_name];
}
[results addObject:row];
}
}
sqlite3_reset(selectStmt);
}
sqlite3_close(SQLDB);
}
else {
printf("DB not exists in application folder\n");
}
return results;
}
/***
Checks for a NULL value
***/
- (NSString*)checkForNull:(char*)colValue {
NSString *returnValue = #"something";
if(colValue) {
returnValue = [NSString stringWithUTF8String:colValue];
}
else {
returnValue = #"nil";
}
return(returnValue);
}
#end
Now the Modal data are
Register.h
#import <Foundation/Foundation.h>
#interface Register : NSObject
#property (nonatomic,retain) NSString *strFirstName;
#property (nonatomic,retain) NSString *strLastName;
#property (nonatomic,retain) NSString *strEmailId;
#property (nonatomic,retain) NSString *strPassword;
#property (nonatomic,retain) NSString *strMobileNo;
#property (nonatomic,retain) NSString *strMilliSeconds;
#property (nonatomic,retain) NSString *IsRegister;
-(id)init;
#end
Register.m
#import "Register.h"
#implementation Register
#synthesize strPassword = _strPassword;
#synthesize strMobileNo = _strMobileNo;
#synthesize strEmailId = _strEmailId;
#synthesize strFirstName = _strFirstName;
#synthesize strLastName = _strLastName;
#synthesize strMilliSeconds = _strMilliSeconds;
#synthesize IsRegister = _IsRegister;
-(id)init
{
self = [super init];
if (self != nil)
{
_strFirstName = [[NSString alloc]init];
_strEmailId = [[NSString alloc]init];
_strPassword = [[NSString alloc]init];
_strLastName = [[NSString alloc]init];
_strMobileNo = [[NSString alloc]init];
_strMilliSeconds = [[NSString alloc]init];
_IsRegister = [[NSString alloc]init];
}
return self;
}
#end
Here I set the intermediate for ViewController(RegisterPage)-DataBase
ViewController_DBConnection.h
#import <Foundation/Foundation.h>
#import "Register.h"
#import "DatabaseOne.h"
#interface ViewController_DBConnection : NSObject
+(void)registerDB:(Register *)registerDB;
+(void)update:(Register *)registerDB;
+(void)delete:(Register *)registerDB;
+(NSMutableArray *)GetRegisterAccount:(NSString *) whereQuery;
+(NSMutableArray *)GetRegisterDetail;
#end
ViewController_DBConnection.m
#import "ViewController_DBConnection.h"
#implementation ViewController_DBConnection
+(void)registerDB:(Register *)registerDB
{
NSString *query = [[NSString alloc]initWithFormat:#"INSERT into TblReg(Firstname,Lastname,EmailId,Password,Mobileno,Milliseconds)values(\"%#\",\"%#\",\"%#\",\"%#\",\"%#\",\"%#\")",registerDB.strFirstName,registerDB.strLastName,registerDB.strEmailId,registerDB.strPassword,registerDB.strMobileNo,registerDB.strMilliSeconds];
BOOL Success = [[DatabaseOne sharedDB]executeQuery:query];
if(Success)
{
[[NSNotificationCenter defaultCenter]postNotificationName:#"Registration Success" object:nil];
}
}
+(void)update:(Register *)registerDB
{
NSString *query = [[NSString alloc]initWithFormat:#"update TblReg Set Firstname = '%#',Lastname = '%#',EmailId = '%#' ,Password = '%#',Mobileno = '%#' WHERE Milliseconds = '%#'",registerDB.strFirstName,registerDB.strLastName,registerDB.strEmailId,registerDB.strPassword,registerDB.strMobileNo,registerDB.strMilliSeconds];
BOOL Success = [[DatabaseOne sharedDB]executeQuery:query];
if(Success)
{
[[NSNotificationCenter defaultCenter]postNotificationName:#"Updation Success" object:nil];
}
}
+(void)delete:(Register *)registerDB
{
NSString *query = [[NSString alloc]initWithFormat:#"DELETE FROM TblReg where Milliseconds = '%#'",registerDB.strMilliSeconds];
BOOL Success = [[DatabaseOne sharedDB]executeQuery:query];
if(Success)
{
[[NSNotificationCenter defaultCenter]postNotificationName:#"Deletion Success" object:nil];
}
}
+(NSMutableArray *)GetRegisterAccount:(NSString *) whereQuery
{
NSString *query=[[NSString alloc]initWithFormat:#"select * from TblReg WHERE %#;", whereQuery];
NSMutableArray *arrayData = [[DatabaseOne sharedDB]executeSelectQuery:query];
return arrayData;
}
+(NSMutableArray *)GetRegisterDetail
{
NSString *query=[[NSString alloc]initWithFormat:#"select * from Register"];
NSMutableArray *arrayData = [[DatabaseOne sharedDB]executeSelectQuery:query];
return arrayData;
}
#end
EditViewController.h
#import <UIKit/UIKit.h>
#import "DatabaseOne.h"
#import "ViewController_DBConnection.h"
#import "Register.h"
#interface EditViewController : UIViewController{
Register *registerDB;
}
#property (strong, nonatomic) IBOutlet UITextField *firstnameTxtFld;
#property (strong, nonatomic) IBOutlet UITextField *lastnameTxtFld;
#property (strong, nonatomic) IBOutlet UITextField *emailidTxtFld;
#property (strong, nonatomic) IBOutlet UITextField *passwordTxtFld;
#property (strong, nonatomic) IBOutlet UITextField *mobilenoTxtFld;
#property (strong, nonatomic) NSString *strMilliSeconds;
#property (strong, nonatomic) NSString *strEmailId;
- (IBAction)actionEdit:(id)sender;
- (IBAction)actionBack:(id)sender;
- (IBAction)actionDeleteRow:(id)sender;
EditViewController.m
#import "EditViewController.h"
#interface EditViewController (){
NSMutableArray *arrayGetDBData;
CGFloat animatedDistance;
}
#end
#implementation EditViewController
#synthesize firstnameTxtFld,lastnameTxtFld,emailidTxtFld,passwordTxtFld,mobilenoTxtFld,strMilliSeconds,strEmailId;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[[DatabaseOne sharedDB] createDB:#"LoginRegistration.sqlite"];
arrayGetDBData = [[NSMutableArray alloc]init];
arrayGetDBData = [ViewController_DBConnection GetRegisterAccount:[NSString stringWithFormat:#"EmailId = \"%#\"",strEmailId]];
registerDB = [[Register alloc]init];
firstnameTxtFld.text = [[arrayGetDBData objectAtIndex:0]valueForKey:#"Firstname"];
lastnameTxtFld.text = [[arrayGetDBData objectAtIndex:0]valueForKey:#"Lastname"];
emailidTxtFld.text = [[arrayGetDBData objectAtIndex:0]valueForKey:#"EmailId"];
passwordTxtFld.text = [[arrayGetDBData objectAtIndex:0]valueForKey:#"Password"];
mobilenoTxtFld.text = [[arrayGetDBData objectAtIndex:0]valueForKey:#"Mobileno"];
registerDB.strMilliSeconds = [[arrayGetDBData objectAtIndex:0]valueForKey:#"Milliseconds"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UITextField Delegate Methods
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.3;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator = (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction < 0.0)
heightFraction = 0.0;
else if (heightFraction > 1.0)
heightFraction = 1.0;
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
//For Checking mail with - ex#m.in
- (BOOL)emailValidation:(NSString *)email {
NSString *emailRegEx =
#"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
#"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
#"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")#(?:(?:[a-z0-9](?:[a-"
#"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
#"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
#"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
#"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
NSPredicate *regExPredicate = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegEx];
BOOL myStringMatchesRegEx = [regExPredicate evaluateWithObject:[email lowercaseString]];
return myStringMatchesRegEx;
}
-(BOOL)isNumeric:(NSString*)inputString{
NSCharacterSet *charcter =[[NSCharacterSet characterSetWithCharactersInString:#"0123456789"] invertedSet];
NSString *filtered;
filtered = [[inputString componentsSeparatedByCharactersInSet:charcter] componentsJoinedByString:#""];
return [inputString isEqualToString:filtered];
}
- (BOOL)checkNumeric:(NSString *)textvalue {
NSCharacterSet *nonNumberSet = [[NSCharacterSet characterSetWithRange:NSMakeRange('0',10)] invertedSet];
NSString *trimmed = [textvalue stringByTrimmingCharactersInSet:[NSCharacterSet symbolCharacterSet]];
BOOL isNumeric = trimmed.length > 0 && [trimmed rangeOfCharacterFromSet:nonNumberSet].location == NSNotFound;
return isNumeric;
}
-(void)getMilliSeconds{
NSDate *now = [[NSDate alloc] init];
NSDateFormatter *datetimeFormatter =[[NSDateFormatter alloc]init];
[datetimeFormatter setDateFormat:#"ddMMyyyyHHmmssSS"];
registerDB.strMilliSeconds=[datetimeFormatter stringFromDate:now];
}
-(void)showAlertController:(NSString *)title passMessage:(NSString *)message{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
}
- (IBAction)actionEdit:(id)sender {
registerDB.strFirstName = firstnameTxtFld.text;
registerDB.strLastName = lastnameTxtFld.text;
registerDB.strEmailId = emailidTxtFld.text;
registerDB.strPassword = passwordTxtFld.text;
registerDB.strMobileNo = mobilenoTxtFld.text;
arrayGetDBData = [ViewController_DBConnection GetRegisterAccount:[NSString stringWithFormat:#"EmailId = \"%#\"",registerDB.strEmailId]];
if([firstnameTxtFld.text length]==0 || [lastnameTxtFld.text length]==0 || [emailidTxtFld.text length]==0 || [mobilenoTxtFld.text length]==0 || [passwordTxtFld.text length]==0){
[self showAlertController:#"Error!" passMessage:#"Please Enter All Fields"];
}
else if([self emailValidation:registerDB.strEmailId] == FALSE){
[self showAlertController:#"Error!" passMessage:#"Please Enter Valid Email Address"];
}
else if([self checkNumeric:registerDB.strMobileNo] == FALSE){
[self showAlertController:#"Error!" passMessage:#"Please Enter Valid Mobile No"];
}
else if([arrayGetDBData count]!=0){
[self showAlertController:#"Warning !" passMessage:#"Already user have this Email Address.Try New?"];
}
else{
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"Updation Success" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updationSuccess:)
name:#"Updation Success"
object:nil];
[ViewController_DBConnection update:registerDB];
}
}
- (IBAction)actionDeleteRow:(id)sender
{
registerDB.strFirstName = firstnameTxtFld.text;
registerDB.strLastName = lastnameTxtFld.text;
registerDB.strEmailId = emailidTxtFld.text;
registerDB.strPassword = passwordTxtFld.text;
registerDB.strMobileNo = mobilenoTxtFld.text;
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"Deletion Success" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(deletionSuccess:)
name:#"Deletion Success"
object:nil];
[ViewController_DBConnection delete:registerDB];
}
- (IBAction)actionBack:(id)sender {
[self.navigationController popToRootViewControllerAnimated:YES];
}
-(void)updationSuccess:(NSNotification *)notification
{
if([[notification name] isEqualToString:#"Updation Success"])
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Success !" message:#"Updated Successfully" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
[self.navigationController popToRootViewControllerAnimated:YES];
}];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
}
-(void)deletionSuccess:(NSNotification *)notification
{
if([[notification name] isEqualToString:#"Deletion Success"])
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Success !" message:#"Deleted Successfully" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
[self.navigationController popToRootViewControllerAnimated:YES];
}];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
}
#end

Save UICollectionViewCell progress state

I've already asked the same question about saving pressed button state and I thought that I should do in the same way to save progress state on cells but my tries are unsuccessful.
What I'm doing now: I select some UICollectionViewCell's and then press "download" button and then downolad action starts. Every cell I selected shows UIProgressView and everything is ok untill I scroll my UICollectionView up or down. When I do it another cells have progress view too but they mustn't! I know that I must save indexPath of selected cells in NSMutableArray and then in cellForItemAtIndexPath check if current cell indexPath is in my array and then show or hide my cell's subviews. I do that but it only works with cell selection! What should I do to save progress view state on each cell this progress really there?
Here is my code:
In cellForItemAtIndexPath:
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];
if ([selecedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]] )
{
cell.selectedBG.hidden = NO;
cell.selectedImg.hidden = NO;
}
else
{
cell.selectedBG.hidden = YES;
cell.selectedImg.hidden = YES;
cell.progressView.hidden = YES;
}
In didSelectItemAtIndexPath:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
...
// Add the selected item into the array
[selectedIds addObject:selectedId];
[selectedVideos addObject:selectedVideo];
AVMVideoCell *collectionCell = (AVMVideoCell*)[collectionView cellForItemAtIndexPath:indexPath];
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];
if ( ![selecedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]] )
{
[selecedCellsArray addObject:[NSString stringWithFormat:#"%ld",(long)indexPath.row]];
collectionCell.selectedBG.hidden = NO;
collectionCell.selectedImg.hidden = NO;
[collectionCell setSelected:YES];
}
}
}
In didDeselectItemAtIndexPath:
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
...
// Delete the selected item from the array
[selectedIds removeObject:selectedId];
[selectedVideos removeObject:selectedVideo];
AVMVideoCell *collectionCell = (AVMVideoCell*)[collectionView cellForItemAtIndexPath:indexPath];
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];
if ( [selecedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]] )
{
[selecedCellsArray removeObject:[NSString stringWithFormat:#"%ld",(long)indexPath.row]];
collectionCell.selectedBG.hidden = YES;
collectionCell.selectedImg.hidden = YES;
[collectionCell setSelected:NO];
}
}
And this is how I show my progress:
-(NSString *)progress:(long long )val1 : (long long )val2 : (AVMVideoCell *)cell : (NSString *)name : (NSIndexPath *)path{
float progress = ((float)val1) / val2;
NSString *prog = [[NSNumber numberWithFloat:progress*100] stringValue];
if (prog != nil){
if(cell.isSelected){
cell.selectedImg.hidden = YES;
cell.progressView.hidden = NO;
}
}
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)path.row];
if ( [selecedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]])
{
[cell.progressView setProgress:progress animated:YES];
}
if([prog intValue]==100){
cell.progressView.hidden = YES;
}
return prog;
}
EDIT: AVMVideoCell.m
#import "AVMVideoCell.h"
#implementation AVMVideoCell
{
NSString *fullUrl;
}
#synthesize imageView;
#synthesize selectedBG;
#synthesize progressLabel;
#synthesize progressView;
#synthesize selectedImg;
#synthesize progLayer;
-(void) setVideo:(AVMDataStore *)video {
if(_video != video) {
_video = video;
}
NSString *durString = [NSString stringWithFormat:#"%#",[self timeFormatted:_video.duration]];
if((_video.filePreview != nil) && ![_video.filePreview isEqualToString:#""]){
fullUrl = [NSString stringWithFormat:#"http://example.com%#",_video.filePreview];
}
NSURL *imgURL = [NSURL URLWithString:fullUrl];
[self.imageView setImageWithURL:imgURL
placeholderImage:[UIImage imageNamed:#"yesterday.png"] options:0 usingActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
self.duration.text = durString;
}
- (NSString *)timeFormatted:(int)totalSeconds
{
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
return [NSString stringWithFormat:#"%02d:%02d:%02d",hours, minutes, seconds];
}
#end
EDIT 2: Explanation about progress
My progressView is not an IBOutlet it's a #property (nonatomic,strong) UIProgressView *progressView; (AVMVideoCell.h)
I allocate and initialize it in cellForItemAtIndexPath:
cell.progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0,0, 150.0f, 1.0f)];
cell.progressView.trackTintColor = [UIColor colorWithWhite:255 alpha:0.5f];
cell.progressView.progressTintColor = [UIColor whiteColor];
[cell.progLayer addSubview:cell.progressView];
cell.progressView.hidden = YES;
cell.progressView.tag = indexPath.row+500;
This is where I call progress change showing:
-(void)downloadStart:(NSString*)fileUrl : (NSString*)name : (AVMVideoCell *) cell : (NSIndexPath *)path{
NSURL *URL = [NSURL URLWithString:fileUrl];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSString *fileName = [NSString stringWithFormat:#"%#.mp4",name]; //set full file name to save
AFHTTPRequestOperation *downloadRequest = [[AFHTTPRequestOperation alloc] initWithRequest:request]; //create download request
[downloadRequest setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSData *data = [[NSData alloc] initWithData:responseObject];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathToFile = [NSString stringWithFormat:#"%#/%#", [paths firstObject],fileName]; // path to 'Documents'
NSString *pathOfFile = [[paths objectAtIndex:0] stringByAppendingPathComponent:fileName];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:pathOfFile append:NO];
BOOL success = [data writeToFile:pathToFile atomically:YES];
if(success){
[self checkIfExists:name : cell :path];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"file downloading error : %#", [error localizedDescription]);
UIAlertView * alert=[[UIAlertView alloc]initWithTitle:#"Error" message:[NSString stringWithFormat:#"%#",error] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil ];
[alert show];
cell.progressView.hidden = YES;
}];
// Step 5: begin asynchronous download
[downloadRequest start];
[downloadRequest setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
[self progress:totalBytesRead :totalBytesExpectedToRead :cell :name : path]; //here I pass val1 and val 2
}];
}
When I select an items in collection view, I gather their model's objects, get each id and make array of urls, then in for..in loop i pass urls one by one and then start async download. You can see how I download and call progress method above.
I need to know if you have a reuse issue or a model issue.
So first try this :
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
...
if (![selectedIds.containsObject:selectedId])
{
// Add the selected item into the array
[selectedIds addObject:selectedId];
[selectedVideos addObject:selectedVideo];
AVMVideoCell *collectionCell = (AVMVideoCell*)[collectionView cellForItemAtIndexPath:indexPath];
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];
if ( ![selecedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]] )
{
[selecedCellsArray addObject:[NSString stringWithFormat:#"%ld",(long)indexPath.row]];
collectionCell.selectedBG.hidden = NO;
collectionCell.selectedImg.hidden = NO;
[collectionCell setSelected:YES];
}
}
else {
// Delete the selected item from the array
[selectedIds removeObject:selectedId];
[selectedVideos removeObject:selectedVideo];
AVMVideoCell *collectionCell = (AVMVideoCell*)[collectionView cellForItemAtIndexPath:indexPath];
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:(unsigned int)indexPath.row];
if ( [selecedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]] )
{
[selecedCellsArray removeObject:[NSString stringWithFormat:#"%ld",(long)indexPath.row]];
collectionCell.selectedBG.hidden = YES;
collectionCell.selectedImg.hidden = YES;
[collectionCell setSelected:NO];
}
}
and remove the didDeselect delegate.
Let me know what happens then.
EDIT :
Ok try this now:
// Lazy instantiation of the progressView
- (UIProgressView *)progressView
{
if (!_progressView)
{
_progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0,0, 150.0f, 1.0f)];
_progressView.trackTintColor = [UIColor colorWithWhite:255 alpha:0.5f];
_progressView.progressTintColor = [UIColor whiteColor];
_progressView.hidden = YES;
[self.contentView addSubview:_progressView];
}
return _progressView;
}
// Here we remove the progressView on reuse
-(void)prepareForReuse
{
[super prepareForReuse];
[self.progressView removeFromSuperview];
self.progressView = nil;
}
Also remove what you did with the progressView with in the cellForItemAtIndexPath method.
You can create class for cell's models, store these models in array in your viewController and use them to get/set all states from/for cells.
Something like this:
#interface CellModel : NSObject
#property(nonatomic) BOOL selected;
#property(nonatomic) NSUInteger progress;
#end
In viewController:
#interface MyViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic) NSArray* models;
#end

SDWebImage displaying wrong images in UITableView

In my iOS app, I'm displaying images inside multiple UITableViewCells. However, it's not displaying the correct images in each cell.
First I load some content from a Feedly stream with the method below:
- (void)loadStreams {
NSString *feedName = [NSString stringWithFormat:#"%#-id", self.category];
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *accessToken = [standardUserDefaults objectForKey:#"AccessToken"];
NSString *feedId = [standardUserDefaults objectForKey:feedName];
NSString *feedPartial = [feedId stringByReplacingOccurrencesOfString:#"/" withString:#"%2F"];
NSString *feedUrl = [NSString stringWithFormat:#"https://sandbox.feedly.com/v3/streams/%#/contents", feedPartial];
NSLog(#"The Feedly url is: %#", feedUrl);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:feedUrl]];
NSMutableURLRequest *mutableRequest = [request mutableCopy];
[mutableRequest addValue:accessToken forHTTPHeaderField:#"Authorization"];
request = [mutableRequest copy];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSArray *jsonArray = (NSArray *)[responseObject objectForKey:#"items"];
self.continuation = [responseObject objectForKey:#"continuation"];
NSMutableArray *tempStreams = [[NSMutableArray alloc] init];
for (NSDictionary *dic in jsonArray) {
NSLog(#"Dic contains: %#", dic);
NSDictionary *originArray = [dic objectForKey:#"origin"];
NSDictionary *visualArray = [dic objectForKey:#"visual"];
NSArray *alternateArray = [dic objectForKey:#"alternate"];
NSDictionary *alternate = [alternateArray objectAtIndex:0];
NSString *image = [visualArray objectForKey:#"url"];
NSString *title = [dic objectForKey:#"title"];
NSString *author = [dic objectForKey:#"author"];
NSString *date = [dic objectForKey:#"published"];
NSDictionary *contentum = [dic objectForKey:#"content"];
NSString *content = [contentum objectForKey:#"content"];
NSString *owner = [originArray objectForKey:#"title"];
NSString *givenid = [dic objectForKey:#"id"];
NSString *href = [alternate objectForKey:#"href"];
NSDate *publisher = [NSDate dateWithTimeIntervalSince1970:([date doubleValue] / 1000.0)];
NSString *published = publisher.timeAgoSinceNow;
NSDictionary *data = [[NSDictionary alloc] initWithObjectsAndKeys:title, #"title", image, #"imageurl", published, #"published", owner, #"owner", content, #"content", givenid, #"givenid", href, #"href", author, #"author", nil];
Stream *stream = [[Stream alloc] initWithDictionary:data];
[tempStreams addObject:stream];
}
self.streams = [[NSMutableArray alloc] initWithArray:tempStreams];
tempStreams = nil;
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Services"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
[operation start];
}
This passes the data to an object called Stream, which consists of the code below:
Stream.h
#import <Foundation/Foundation.h>
#interface Stream : NSObject
#property (strong, nonatomic)NSString *name;
#property (strong, nonatomic)NSString *thumbnail;
#property (strong, nonatomic)NSString *photo;
#property (strong, nonatomic)NSString *published;
#property (strong, nonatomic)NSString *content;
#property (strong, nonatomic)NSString *givenid;
#property (strong, nonatomic)NSString *linky;
#property (strong, nonatomic)NSString *author;
- (id)initWithName:(NSString *)aName
thumbnail:(NSString *)aThumbnail
photo:(NSString *)aPhoto
published:(NSString *)aPublished
content:(NSString *)aContent
givenid:(NSString *)aId
linky:(NSString *)aLinky
author:(NSString *)aAuthor;
- (id)initWithDictionary:(NSDictionary *)dic;
#end
Stream.m
#import "Stream.h"
#implementation Stream
//The designed initializer
- (id)initWithName:(NSString *)aName
thumbnail:(NSString *)aThumbnail
photo:(NSString *)aPhoto
published:(NSString *)aPublished
content:(NSString *)aContent
givenid:(NSString *)aId
linky:(NSString *)aLinky
author:(NSString *)aAuthor{
self = [super init];
if (self) {
self.name = aName;
self.thumbnail = aThumbnail;
self.photo = aPhoto;
self.published = aPublished;
self.content = aContent;
self.givenid = aId;
self.linky = aLinky;
self.author = aAuthor;
}
return self;
}
- (id)initWithDictionary:(NSDictionary *)dic {
self = [self initWithName:dic[#"title"] thumbnail:dic[#"imageurl"] photo:dic[#"imageurl"] published:dic[#"published"] content:dic[#"content"] givenid:dic[#"givenid"] linky:dic[#"href"] author:dic[#"author"]];
return self;
}
- (id)init {
self = [self initWithName:#"Undifined" thumbnail:#"Undifined" photo:#"Undifined" published:#"Undifined" content:#"Undifined" givenid:#"Undifined" linky:#"Undifined" author:#"Undifined"];
return self;
}
#end
And in the end I build a cell like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * reuseIdentifier = #"programmaticCell";
MGSwipeTableCell * cell = [self.tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell) {
cell = [[MGSwipeTableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
}
CGFloat brightness = [UIScreen mainScreen].brightness;
cell.textLabel.text = [self.streams[indexPath.row] name];
cell.detailTextLabel.text = [self.streams[indexPath.row] published];
NSString *imageUrl = [NSString stringWithFormat: #"%#", [self.streams[indexPath.row] photo]];
NSLog(#"Image is: %# and path is: %d", imageUrl, indexPath.row);
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:imageUrl]
placeholderImage:[UIImage imageNamed:#"tile-blue.png"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0];
cell.delegate = self; //optional
return cell;
}
What happens though, is that it displays the wrong image in a lot of cells and sometimes the same image for a couple of cells. What am I doing wrong here?
These are symptoms of cell reuse. There are two issues you will have to deal with.
(1) you should reset your cell's content before it is reused. To do this you can override prepareForReuse in the cell and nil out the relevant properties (such as cell.imageView). If you don't do this, you will see the old image -after- the cell has been recycled, before SDWebImage has assigned a new image.
(2) as SDWebImage image retrieval is async, the image may arrive after the cell has scrolled off the screen (and recycled with new content. You need to check whether the image is still relevant before assigning it to the imageView. I am not sure if this is possible with the SDWebImage UIImageView category method. You may have to dissect SDWebImage a little . You can get more control over the process using the SDWebImageManager method:
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url
options:(SDWebImageOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageCompletionWithFinishedBlock)completedBlock;
You could use it something like this (in CellForRowAtIndexPath)
[[SDWebImageManager defaultManager] downloadImageWithURL:url
options:0
progress:nil
completed:
^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if ([[tableView indexPathForCell:cell] isEqual:indexPath]) {
//image is still valid for this cell
cell.image = image;
}
}];
Push a unique id on the stack before your closure and check it when your closure completes
prepareForReuse
Like this:
func updateArtistImage(url: URL) {
let _eventId = self.event?.id
SDWebImageManager.shared().loadImage(with: url, options: [], progress: nil) { (image, data, error, cacheType, finished, url) in
if self.event!.id == _eventId {
if error == nil {
self.artistImageView.image = image
} else {
self.artistImageView.image = UIImage(named: "error_image")
}
}
}
}
and this:
override func prepareForReuse() {
super.prepareForReuse()
self.artistImageView.image = nil
}

FileBrowser UITableViewController, Delegate doesn't work

i decided to create a simple FileBrowser using UITableViewController with delegate which detect the file you chosen,
and i presented the UITableViewController like that
fbVC = [[FileBrowserTableViewController alloc] init];
fbVC.delegate = self;
fbVC.path = #"/";
navigationController = [[UINavigationController alloc] initWithRootViewController:fbVC];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
and added the delegate method in the other class
- (void)fileBrowser:(FileBrowserTableViewController *)fileBrowser didFinishWithFileURL:(NSURL *)fileURLPath {
NSString *extString = [fileURLPath absoluteString];
NSString *ext = [[extString pathExtension] lowercaseString];
NSString* theFileName = [[extString lastPathComponent] stringByDeletingPathExtension];
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileURLPath.pathExtension, NULL);
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
NSString *MIMETypeString = (__bridge NSString*)MIMEType;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"FileBrowser" message:[NSString stringWithFormat:#"---URL : %# --FileName : %# --ext %#: mimetype : %#", fileURLPath, theFileName, fileURLPath.pathExtension, MIMETypeString] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
[self.companion sendDocumentsAtPath:fileURLPath fileName:[NSString stringWithFormat:#"[TGEnhancer]%#.%#",theFileName, fileURLPath.pathExtension] mimeType:MIMETypeString];
// [fileBrowser.navigationController popViewControllerAnimated:YES];
[fileBrowser.navigationController dismissViewControllerAnimated:YES completion:^{
NSLog(#"File Browser - Finished");
}];
}
but for some reason the delegate works only from the first page of UINavigationController
here is my .h file
#protocol FileBrowserTableViewControllerDelegate;
#interface FileBrowserTableViewController : UITableViewController
{
NSString *path;
NSMutableArray *files;
}
#property (nonatomic,retain) NSString *path;
#property (nonatomic,retain) NSMutableArray *files;
#property (nonatomic, strong) id<FileBrowserTableViewControllerDelegate> delegate;
#end
#protocol FileBrowserTableViewControllerDelegate <NSObject>
#optional
- (void)fileBrowser:(FileBrowserTableViewController *)fileBrowser didFinishWithFileURL:(NSURL *)fileURLPath;
- (void)fileBrowserDidCancel:(FileBrowserTableViewController *)fileBrowser;
#end
my didSelectRowAtIndexPath method here
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
File *aFile = [files objectAtIndex:indexPath.row];
if(aFile.isDirectory)
{
FileBrowserTableViewController *anotherViewController = [[FileBrowserTableViewController alloc] init];
anotherViewController.path = [path stringByAppendingPathComponent:aFile.name];
[self.navigationController pushViewController:anotherViewController animated:YES];
} else {
[self doOpenFileAtIndexPath:indexPath];
}
}
- (void)doOpenFileAtIndexPath:(NSIndexPath*)indexPath {
// File *aFile = [files objectAtIndex:indexPath.row];
[self openFileAtIndexPath:indexPath];
}
- (void)openFileAtIndexPath:(NSIndexPath*)indexPath
{
File *aFile = [files objectAtIndex:indexPath.row];
NSString *extension = [[aFile.name pathExtension] lowercaseString];
NSString *fullpath = [path stringByAppendingPathComponent:aFile.name];
NSURL *filePathUrl = [NSURL fileURLWithPath:fullpath];
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:#"Type Existe"
message:[NSString stringWithFormat:#"--Name : %# Fullpath : %#", aFile.name, fullpath]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[self.delegate fileBrowser:self didFinishWithFileURL:filePathUrl];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
anyone can help me and tell me What exactly make delegate works (once) within UINavigationController ? specially from the first path only ( if i open another path and choose a file, it won't work.
Thanks
OPs i think i find the solution by myself, my mistake was in didSelectRowAtIndexPath method
i wasn't calling the delegate again.
here the code worked for me
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
File *aFile = [files objectAtIndex:indexPath.row];
if(aFile.isDirectory)
{
FileBrowserTableViewController *anotherViewController = [[FileBrowserTableViewController alloc] init];
anotherViewController.path = [path stringByAppendingPathComponent:aFile.name];
anotherViewController.delegate = self.delegate;
[self.navigationController pushViewController:anotherViewController animated:YES];
} else {
[self doOpenFileAtIndexPath:indexPath];
}
}
Thanks again.. hope it helps others..

icon grey custom UIActivityViewController

I create a custom UIActivityViewController but when I load the icons that I do makes me see gray and you are pretty much loaded correctly, someone did it happen? how you have remedied?
ActivityViewCustomActivity *ca = [[ActivityViewCustomActivity alloc]init];
ca.service = #"avanti";
ca.image = image;
ca.act = #"com.avanti.app";
ActivityViewCustomActivity *fa = [[ActivityViewCustomActivity alloc]init];
fa.service = #"facebook";
fa.image = image;//[UIImage imageNamed:#"icon-facebook.jpg"];
fa.act = #"com.facebook.app";
ActivityViewCustomActivity *tw = [[ActivityViewCustomActivity alloc]init];
tw.service = #"twitter";
tw.image = image;
tw.act = #"com.twitter.app";
UIActivityViewController *activityVC =
[[UIActivityViewController alloc] initWithActivityItems:items
applicationActivities:#[ca,fa,tw]];
activityVC.excludedActivityTypes = #[UIActivityTypePostToTwitter,UIActivityTypePostToFacebook,UIActivityTypeMail,UIActivityTypePostToWeibo, UIActivityTypeAssignToContact, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeSaveToCameraRoll];
activityVC.completionHandler = ^(NSString *activityType, BOOL completed)
{
if ([activityType isEqualToString:#"com.avanti.app"]) {
NSLog(#" activityType: %#", activityType);
NSLog(#" completed: %i", completed);
NSString *name = [q objectAtIndex:indexPath.row];
UIStoryboard *storyboar = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
ListViewController *list = [storyboar instantiateViewControllerWithIdentifier:#"ListViewController"];
list.ide = ide;
list.canale = name;
[self.navigationController pushViewController:list animated:YES];
}
else if ([activityType isEqualToString:#"com.facebook.app"]){
NSLog(#" activityType: %#", activityType);
NSLog(#" completed: %i", completed);
UIActionSheet *action = [[UIActionSheet alloc]initWithTitle:#"Facebook" delegate:self cancelButtonTitle:#"Annulla" destructiveButtonTitle:#"Vuoi pubblicarlo ?" otherButtonTitles:#"ok", nil];
action.actionSheetStyle = UIActionSheetStyleDefault;
[self actionSheet:action clickedButtonAtIndex:2];
[action showInView:[self.view window]];
}
else if ([activityType isEqualToString:#"com.twitter.app"]){
NSLog(#" activityType: %#", activityType);
NSLog(#" completed: %i", completed);
[self shareTwitter];
}
};
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
NSLog(#"ipad");
}
else
{
[self presentViewController:activityVC animated:YES completion:nil];
}
}
e l'activity è così
- (NSString *)activityType
{
return act;
}
- (NSString *)activityTitle
{
return service;
}
- (UIImage *)activityImage
{
// CGRect rect = CGRectMake(0.0f, 0.0f, 85.0f, 85.0f);
// UIGraphicsBeginImageContext(rect.size);
//
// rect = CGRectInset(rect, 15.0f, 15.0f);
// UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:10.0f];
// [path stroke];
//
// rect = CGRectInset(rect, 0.0f, 10.0f);
// [service drawInRect:rect withFont:[UIFont fontWithName:#"Futura" size:15.0f] lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentCenter];
//
// UIImage *imag = UIGraphicsGetImageFromCurrentImageContext();
//
// UIGraphicsEndImageContext();
// //UIImage *ima = [UIImage imageNamed:#"facebook.jpg"];
// return imag;
UIImage *ima = [UIImage imageNamed:#"Icon_Facebook.png"];
return ima;
// if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
// {
// return [UIImage imageNamed:#"Facebook_43x43"];
// }
// else
// {
// return image;
// }
}
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
{
NSLog(#"%s", __FUNCTION__);
for (id obj in activityItems) {
if ([obj isKindOfClass:[NSString class]]) {
return YES;
}
}
return NO;
}
- (void)prepareWithActivityItems:(NSArray *)activityItems
{
NSLog(#"%s",__FUNCTION__);
}
- (UIViewController *)activityViewController
{
NSLog(#"%s",__FUNCTION__);
return nil;
}
- (void)performActivity
{
// This is where you can do anything you want, and is the whole reason for creating a custom
// UIActivity
[self activityDidFinish:YES];
}
+ (UIActivityCategory)activityCategory
{
return UIActivityCategoryShare;
}
and the screenshot is here http://i57.tinypic.com/332vtjo.png
and .h is
#import <UIKit/UIKit.h>
#interface ActivityViewCustomActivity : UIActivity
#property (nonatomic, strong) NSString *service;
#property (nonatomic, strong) UIImage *image;
#property (nonatomic, strong) NSString *act;
- (NSString *)activityType;
- (NSString *)activityTitle;
- (UIImage *)activityImage;
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems;
- (void)prepareWithActivityItems:(NSArray *)activityItems;
- (UIViewController *)activityViewController;
- (void)performActivity;
+ (UIActivityCategory)activityCategory;
#end
Try to add _ to your activityImage function
Something like
- (UIImage *)_activityImage
{
return [UIImage imageNamed:#"Icon_Facebook.png"];
}

Resources