watch kit extension connect using SQLite - ios

I need help how to connect my SQLite database to my watchkit app extension. Im not much familiar in using sqlite with cell rows. Any easy sample codes will be a great help thanks. Below are sample arrays i used for example.
#import "ICBQuoteSource.h"
#implementation ICBQuoteSource
+(NSArray *)quoteDictionary {
NSMutableArray *quotes = [NSMutableArray new];
[quotes addObject:#{#"characterImage": #"moss", #"characterName": #"Moss", #"quote": #"I came here to drink milk and kick ass... and I've just finished my milk."}];
[quotes addObject:#{#"characterImage": #"roy", #"characterName": #"Roy", #"quote": #"Hello, IT, have you tried turning it off and on again?"}];
[quotes addObject:#{#"characterImage": #"moss", #"characterName": #"Moss", #"quote": #"Did you see that ludicrous display last night?"}];
[quotes addObject:#{#"characterImage": #"denholm", #"characterName": #"Denholm", #"quote": #"That's the sort of place this is, Jen. A lot of sexy people not doing much work and having affairs."}];
[quotes addObject:#{#"characterImage": #"moss", #"characterName": #"Moss", #"quote": #"This Jen is the Internet"}];
return [NSArray arrayWithArray:quotes];
}
#end
#import "InterfaceController.h"
#import "ICBQuoteSource.h"
#import "rowController.h"
#interface InterfaceController()
#property (nonatomic, strong) NSArray *quotes;
#end
#implementation InterfaceController
- (void)awakeWithContext:(id)context
{
[super awakeWithContext:context];
// Get quotes
self.quotes = [ICBQuoteSource quoteDictionary];
// Set number of table Row
[self.table setNumberOfRows:self.quotes.count withRowType:#"Row Controller"];
// Set row properties
for (NSDictionary *quote in self.quotes) {
rowController *quoteRow = [self.table rowControllerAtIndex:[self.quotes indexOfObject:quote]];
[quoteRow.englishTxtLabel setText:quote[#"characterName"]];
[quoteRow.translationTxtLabel setText:quote[#"quote"]];
}
}
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
}
#end

You haven't actually stated what the problem is...so let me attempt to guess. I'm assuming that the rows are not showing up properly in your table. What I would suggest trying is moving your row set up logic into willActivate. This is something I found when working with tables in Xcode 6.2b5. You would not get the appropriate behavior in awakeWithContext(:).
Hopefully that helps lead you in the right direction. If this isn't the actual problem you are having, then please edit your question and I'll edit my answer accordingly.

Related

Accessing Variables in another class and dividing NSString

Hy I have a problem accessing variables in another class.
Im making an app that makes note and let you study from the notes you make, for example the user makes a note that says "Oceanic dolphins: are members of the cetacean...", and when the user press a button to study it appears something like this "what are Oceanic Dolphins" then the user press a button it appears something like this "they are members of the cetacean..." the problem I have is this When i enter the ViewController that makes the question it appears empty I think the problem lies on one of the next codes
I make the Variable Globals like this
QueRes.h
#import <Foundation/Foundation.h>
#interface QueRes : NSObject
#property NSString *question;
#property NSString *response;
#end
QueRes.m
#import "QueRes.h"
#implementation QueRes
#end
I divide the NSString of the note like this
NSArray *card = [_argumentTextView.text componentsSeparatedByString:#":"];
QueRes *make = [[QueRes alloc] init];
if ([card count] >= 2)
{
make.question = card [0];
make.response = card [1];
}
the I apply the variable question and response in a ViewController like this
- (void)viewDidLoad
{
[super viewDidLoad];
QueRes *make = [[QueRes alloc] init];
_questionTextView.text = make.question;
}
then in other view controller i have the same code but apply with the response variable
Please help me I been stuck in this for weeks (I have Xcode 5 and the app runs in IOS 7)
(if you need more of the code of the program to help me fix it just tell me )
You are making a new instance of a QueRes in your viewDidLoad method. Unless the init method of QueRes sets its question and response properties to something, they will be uninitialized, which is why you are not seeing anything in your text view: there is nothing to show.
Naming the QueRes instance you make in the third code block you posted make does not make it the same instance as the instance in the viewDidLoad method, and it is not a global variable at all. It is a separate instance of QueRes.

Store an NSArray globally to save data bandwidth from downloading content

I am making an application which as a part of it needs to download information from 2 RSS feeds.
However these feeds will have that information used across the entire app and may or may not be reloaded as the user requires to see their selected UIViewController.
So my question is:
Is it advisable to setup these arrays on application load in the UIAppDelegate or is that a big no-no in regards to performance?
I have the code working, I am just wanting to know what the best place would be to execute it to minimize data usage and also at the same time be best accessible throughout the app?
Any help would be great, because there is a lot of code to shift around if I need to keep re-doing this.
Thanks for the advice.
PS I know there is a lot of reading I can do and am doing, using SO is part of this research to get developers opinions. I hope that it does not break any rules or upset people :-)
Create a File as an NSObject, do header like this;
#interface myData : NSObject
{
NSMutableArray *myDataArray;
}
#property (nonatomic, retain) NSMutableArray *myDataArray;
+ (myData *)sharedData;
#end
Then in the .m add this
#import “myData.h”
static myData *sharedData;
#implementation myData
#synthesize myDataArray;
+ (myData *)sharedData
{
if(!sharedData)
{
sharedData = [[myData alloc] init];
}
return sharedData;
}
- (id)init
{
self = [super init];
if(self)
{
myDataArray = [[NSMutableArray alloc] init];
}
return self;
}
Then in each of your VCs, simply #import "myData.h" and when you need it do this;
myData *localShared = [myData sharedData];
localShared.myDataArray = // This is your array and will look the same throughout
NSString *myStringObj = localShared.myDataArray[4]; // So you can do this kind of stuff
This from memory, I have not tested but I think this is very close. Hope it helps.

ios ARC table bad access

for my table view I have the following going on (paraphrased)
.h
#interface OptionsView : UIView <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, retain) NSArray *dataSource;
.m
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
...
self.dataSource = [NSArray arrayWithObjects:options, sections, sponsor, nil];
}
return self;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(self.dataSource) {
NSArray *ds = [self.dataSource objectAtIndex:indexPath.section];
NSDictionary *d = [ds objectAtIndex:indexPath.row];
ActionBlock a = [d objectForKey:ACTION]; // <-- Thread 1: EXC_BAD_ACCESS (code=2, address=0x802)
if(a != nil) a();
}
}
You can see that in my didSelectRowAtIndexPath I'm getting an EXC_BAD_ACCESS but I'm not sure why. Because I'm using arc it isn't a zombie problem (already checked).
Using breakpoints I see that the self.dataSource exists after it's initialized, but not later when it's needed. It doesn't show up as <nil> either, it's just white space. Also, this works in debug but not in release so what does that mean?
** EDIT adding a screenshot **
You will notice that neither ds or d show up.. odd?
So there's two places I can see that might cause the problem. First, what is ACTION? Is it some sort of NSString? Just want to make sure that you're using a valid key object. Second, (and more likely the problem), it looks like ActionBlock is some kind of code block you're storing in a collection array. Are you copying that block before you store it in the array/dictionary? You must copy any block you intend on keeping around (storing) longer than the scope it was created in. This is easy to do. For example:
void (^NewBlock)(void) = [^{
....code....
} copy];
Alternately:
void (^NewBlock)(void) = ^{
....code....
};
[dictionary setObject:[NewBlock copy] forKey:ACTION]; //Assuming #define ACTION #"action"
This copies it onto the heap so that it can be stored. If you don't copy it, you'll get BAD_EXC_ACCESS anytime you try to reference the block outside the scope it was created in.
It seems you´re using a UIViewController instead of a UITableViewController. If I remember correctly, you have to go to the inspector and drag the delegate and datasource from the tableView to the UIViewController. I don´t remember exactly and I´m not on my computer but I´m sure I did it several times before I began to use a UITableViewController for every tableView I have.
Oh, and i wouldn´t use dataSource as a name for your array. Just to prevent naming conflicts.

ios alloc-release

My app is receiving memory warnings because it's asking for lot of memory. I try to release every allocation. However, sometimes I don't know how to do it.
For example: I have two pairs of .h and .m file. One of them makes connections with a server and the other with local SQLite.
Usually, the code which calls to a method from those files are like this:
-(NSMutableArray *) getRecentActivity{
LocalStorageController *local = [[LocalStorageController alloc]init];
return [local getRecentActivity];
}
getRecentActivity returns a NSMutableArray.
Well, in that piece of code we can see that I am allocating memory for the LocalStorageController but I never call to the release method so, I suppose, the more I call that function, the more memory I will be allocating.
If I call autorelease after init, it will crash.
Moreover, usually, I use this other kind of code:
ServerConnection *serv = [[ServerConnection alloc]init];
NSMutableArray list = [serv getMyListOfContacts];
Which uses ASIHTTPRequest and, if I call [serv release]; after the second line, the app crashes with EXC_BAD_ACCESS pointing to a line in ASIHTTPRequest library.
How is suppose to manage this situation?
Thank you very much!
The first case is easy;
-(NSMutableArray *) getRecentActivity{
LocalStorageController *local = [[LocalStorageController alloc]init];
NSMutableArray *tmp = [local getRecentActivity];
[local release];
return tmp;
}
The second case is hard to solve in a general way without seeing more of the actual code.
Using serv as a property would be fixing this retain/release problem.
In your .h:
#property (nonatomic, retain) ServerConnection *server;
In your .m:
#synthesize server;
- (void)dealloc {
[server release];
// The rest of your releases here...
[super dealloc];
}
- (void)yourMethod {
ServerConnection *myServConnection = [[ServerConnection alloc] init];
self.serv = myServConnection;
[myServConnection release];
NSMutableArray list = [self.serv getMyListOfContacts];
}
Just keep on using self.serv in this class from that point on and you won't have a problem with having the object being released.

Does the iOS SDK provide queues and stacks?

I'm writing an iPhone app, and I'm surprised that there seem to be no NSQueue or NSStack classes in Apple's Foundation Framework. I see that it would be quite easy to roll my own, starting with an NSMutableArray, so I'll do that unless I've missed something. Have I missed something?
Here's my Stack class, in case it's useful to those who come after me. As you can see, the pop method involves enough code that you'd want to factor it out.
Stack.h:
#import <Foundation/Foundation.h>
#interface Stack : NSObject {
NSMutableArray *contents;
}
- (void)push:(id)object;
- (id)pop;
#end
Stack.m
#import "Stack.h"
#implementation Stack
// superclass overrides
- (id)init {
if (self = [super init]) {
contents = [[NSMutableArray alloc] init];
}
return self;
}
- (void)dealloc {
[contents release];
[super dealloc];
}
// Stack methods
- (void)push:(id)object {
[contents addObject:object];
}
- (id)pop {
id returnObject = [[contents lastObject] retain];
if (returnObject) {
[contents removeLastObject];
}
return [returnObject autorelease];
}
#end
as far as I know there is no generic class avaialbe. Try using the NSMutableArray, add via addObject and get first/last via objectAtIndex and removeObjectAtIndex.
Another easy way would be to extend NSMutableArray's capabilities by making use of Objective C's categories. You can do that by adding two files to your project:
NSMutableArray+Stack.h
#interface NSMutableArray (StackExtension)
- (void)push:(id)object;
- (id)pop;
#end
NSMutableArray+Stack.m
#import "NSMutableArray+Stack.h"
#implementation NSMutableArray (StackExtension)
- (void)push:(id)object {
[self addObject:object];
}
- (id)pop {
id lastObject = [self lastObject];
[self removeLastObject];
return lastObject;
}
#end
Now you can use a regular NSMutableArray in every other file of your project like a stack and call push or pop on that object. Don't forget to #import NSMutableArray+Stack.h in those files. Here is some sample code how you can use your new NSMutableArray as a stack:
NSMutableArray *myStack = [[NSMutableArray alloc] init]; // stack size = 0
NSString *aString = #"hello world";
[myStack push:myString]; // stack size = 1
NSString *anotherString = #"hello universe";
[myStack push:anotherString]; // stack size = 2
NSString *topMostStackObject;
topMostStackObject = [myStack pop]; // stack size = 1
NSLog("%#",topMostStackObject);
topMostStackObject = [myStack pop]; // stack size = 0
NSLog("%#",topMostStackObject);
The log output will be:
hello universe
hello world
I'm a bit late to this party, but are you aware of CHDataStructures?
http://cocoaheads.byu.edu/code/CHDataStructures
I have put a working iOS Objective C queue object on GitHub. The code was taken from various posts and by no means is owned by me.
https://github.com/esromneb/ios-queue-object/
If you see any problems please fork, and make a pull request!
Yes, an NSMutableArray doubles as a stack or queue. (It would be slightly inefficient as a queue.)
You could also use C++'s stack and queue adapter, but it makes memory management a bit messy if you want to store Objective-C objects with it.
ObjectiveSugar is a very popular CocoaPod that provides, among a bunch of other great stuff, push and pop API calls on NSMutableArray. Sure, it's not in the iOS SDK, but I'm sharing it here because I was looking for the same thing, and this was the solution I went with (and it certainly didn't hurt that we were already using this CocoaPod in our codebase).
No. You missed nothing. That's all. Objective-C is higher level language look like C. Low level control is not required.
Cocoa classes are designed for easier use than efficiency. If you want to deal with performance, you have an option of raw C (or C++) implementation. Otherwise, just use easy way. Of course, early-optimization is evil.
If you want a kind of encapsulation, just make a new class which contains NSMutableArray within it. Hide inner NSMutableArray and just expose what you want. But you'll realize this is unnecessary.

Resources