Commit a1ceceb5 authored by Alf Watt's avatar Alf Watt

Cleanup the URL methods to match the underlying NSBundle

Clean out some Plist cruft
Updated to recommended builds settings
Update the README
parent 672c450d
......@@ -20,7 +20,7 @@
75E666D01A36E4C2001E7DC4 /* LiveBundle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveBundle.h; sourceTree = "<group>"; };
75E666F01A36E4E9001E7DC4 /* NSBundle+LiveBundle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+LiveBundle.h"; sourceTree = "<group>"; };
75E666F11A36E4E9001E7DC4 /* NSBundle+LiveBundle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+LiveBundle.m"; sourceTree = "<group>"; };
75E666F41A36E56E001E7DC4 /* readme.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = readme.md; sourceTree = "<group>"; };
75E666F41A36E56E001E7DC4 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
75E666F51A3711BE001E7DC4 /* NSDate+RFC1123.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+RFC1123.h"; sourceTree = "<group>"; };
75E666F61A3711BE001E7DC4 /* NSDate+RFC1123.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+RFC1123.m"; sourceTree = "<group>"; };
/* End PBXFileReference section */
......@@ -39,7 +39,7 @@
75E666C11A36E4C2001E7DC4 = {
isa = PBXGroup;
children = (
75E666F41A36E56E001E7DC4 /* readme.md */,
75E666F41A36E56E001E7DC4 /* README.md */,
75E666CD1A36E4C2001E7DC4 /* LiveBundle */,
75E666CC1A36E4C2001E7DC4 /* Products */,
);
......@@ -106,7 +106,7 @@
75E666C21A36E4C2001E7DC4 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0610;
LastUpgradeCheck = 0730;
ORGANIZATIONNAME = iStumbler;
TargetAttributes = {
75E666CA1A36E4C2001E7DC4 = {
......@@ -174,6 +174,7 @@
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
......@@ -246,6 +247,7 @@
INFOPLIST_FILE = LiveBundle/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.istumbler.labs.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
......@@ -263,6 +265,7 @@
INFOPLIST_FILE = LiveBundle/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.istumbler.labs.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
......@@ -287,6 +290,7 @@
75E666E31A36E4C3001E7DC4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
......
......@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>net.istumbler.labs.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
......@@ -22,7 +22,5 @@
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015 iStumbler. All rights reserved.</string>
<key>ILLiveBundleURLKey</key>
<string>https://istumbler.net/bundles/</string>
</dict>
</plist>
......@@ -24,7 +24,7 @@ extern NSString* const NSBundlePlistType;
- (NSString*) tempPathForResourceURL:(NSURL*) download;
/** @returns the remote URL for the resource specified */
- (NSURL*) liveURLForResource:(NSString*) resource ofType:(NSString*) type;
- (NSURL*) liveURLForResource:(NSString*) resource withExtension:(NSString*) type;
/** @returns the live path for the remote URL specified */
- (NSString*) livePathForResourceURL:(NSURL*) download;
......
......@@ -44,7 +44,7 @@ NSString* const NSBundlePlistType = @"plist";
stringByAppendingPathComponent:[self bundleIdentifier]];
}
- (NSURL*) liveURLForResource:(NSString*) resource ofType:(NSString*) type
- (NSURL*) liveURLForResource:(NSString*) resource withExtension:(NSString*) type
{
NSString* liveBundleURL = [[self infoDictionary] objectForKey:ILLiveBundleURLKey]; // this is set per-bundle
return [NSURL URLWithString:[[liveBundleURL stringByAppendingPathComponent:resource] stringByAppendingPathExtension:type]];
......@@ -76,7 +76,7 @@ NSString* const NSBundlePlistType = @"plist";
- (NSString*) livePathForResource:(NSString*) resource ofType:(NSString*) type
{
NSURL* liveResourceURL = [self liveURLForResource:resource ofType:type];
NSURL* liveResourceURL = [self liveURLForResource:resource withExtension:type];
NSString* staticPath = [self pathForResource:resource ofType:type];
NSString* liveResourcePath = [self livePathForResourceURL:liveResourceURL]; // this interns the string
......
# LiveBundle
## Keep your Resources Fresh
NSBundle category to provide dynamic updating of resources from your web server.
NSBundle+LiveBundle is a category to provide dynamic updating of resources from your web server.
Let's say you have a resource, any resource will do, but for e.g. this product_table.plist which displays
a lis of your companies products in a custom view inside MyApplication:
......@@ -18,26 +19,27 @@ so that your app can check to see if there is an updated version of the resource
https://exaple.com/support/livebundle/com.example.myapplication/products_table.plist
LiveBundle makes a If-Modified-Since request to your server when the resource is requested. It then downloads
the resource, and copies it into the users's library folder:
the resource, and copies it into the users's library folder (or it's sandboxed equivalent):
~/Library/Application Support/MyApplication/LiveBundle/com.example.myapplication/products_table.plist
And that's the path that your code sees when it asks for the resource:
NSString* live_path = [[NSBundle mainBundle] livePathForResource:@"products_table" of type:@"plist"];
NSDictionary* products_table = [NSDictionary dictionaryWithContentsOfFile:livePath];
And that's the object that you can subscribe to be notified for updates to (or just watch the file path yourelf):
[[NSNotificationCenter defaultCenter] addObserverForName:ILLiveBundleResourceUpdateNote
object:live_path
queue:nil
usingBlock:^(NSNotification *note)
{
NSLog(@"%@ was updated!", [note object]);
products_table = [NSDictionary dictionaryWithContentsOfFile:livePath];
// update the ui...
}];
NSString* livePath = [[NSBundle mainBundle] livePathForResource:@"productsTable" ofType:@"plist"];
NSDictionary* productsTable = [NSDictionary dictionaryWithContentsOfFile:livePath];
// Subscribe to be notified for updates to the file path (or just watch the file path yourelf):
[[NSNotificationCenter defaultCenter]
addObserverForName:ILLiveBundleResourceUpdateNote
object:livePth
queue:nil
usingBlock:^(NSNotification *note)
{
NSLog(@"%@ was updated!", [note object]);
products_table = [NSDictionary dictionaryWithContentsOfFile:livePath];
// update the ui...
}];
This works well for data that changes on a weekly or monthly basis, the app should only check a URL once per launch.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment