mirror of
https://github.com/samsonjs/5by5Browser.git
synced 2026-04-12 12:05:47 +00:00
first commit
This commit is contained in:
commit
15c1744e66
51 changed files with 5151 additions and 0 deletions
489
5by5Browser.xcodeproj/project.pbxproj
Normal file
489
5by5Browser.xcodeproj/project.pbxproj
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
7B043E87149D6984004B52E8 /* back.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B043E83149D6984004B52E8 /* back.png */; };
|
||||
7B043E88149D6984004B52E8 /* back@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B043E84149D6984004B52E8 /* back@2x.png */; };
|
||||
7B043E89149D6984004B52E8 /* forw.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B043E85149D6984004B52E8 /* forw.png */; };
|
||||
7B043E8A149D6984004B52E8 /* forw@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B043E86149D6984004B52E8 /* forw@2x.png */; };
|
||||
7B043E8E149D6FA0004B52E8 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B043E8C149D6FA0004B52E8 /* icon.png */; };
|
||||
7B043E8F149D6FA0004B52E8 /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B043E8D149D6FA0004B52E8 /* icon@2x.png */; };
|
||||
7B1A6ECF149D140600FC5105 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B1A6ECE149D140600FC5105 /* UIKit.framework */; };
|
||||
7B1A6ED1149D140600FC5105 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B1A6ED0149D140600FC5105 /* Foundation.framework */; };
|
||||
7B1A6ED3149D140600FC5105 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B1A6ED2149D140600FC5105 /* CoreGraphics.framework */; };
|
||||
7B1A6ED9149D140600FC5105 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7B1A6ED7149D140600FC5105 /* InfoPlist.strings */; };
|
||||
7B1A6EDB149D140600FC5105 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1A6EDA149D140600FC5105 /* main.m */; };
|
||||
7B1A6EDF149D140600FC5105 /* SSAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1A6EDE149D140600FC5105 /* SSAppDelegate.m */; };
|
||||
7B1A6EE2149D140600FC5105 /* SSMasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1A6EE1149D140600FC5105 /* SSMasterViewController.m */; };
|
||||
7B1A6EE5149D140600FC5105 /* SSDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1A6EE4149D140600FC5105 /* SSDetailViewController.m */; };
|
||||
7B1A6EE8149D140600FC5105 /* SSMasterViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B1A6EE6149D140600FC5105 /* SSMasterViewController_iPhone.xib */; };
|
||||
7B1A6EEB149D140600FC5105 /* SSMasterViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B1A6EE9149D140600FC5105 /* SSMasterViewController_iPad.xib */; };
|
||||
7B1A6EEE149D140600FC5105 /* SSDetailViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B1A6EEC149D140600FC5105 /* SSDetailViewController_iPhone.xib */; };
|
||||
7B1A6EF1149D140600FC5105 /* SSDetailViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B1A6EEF149D140600FC5105 /* SSDetailViewController_iPad.xib */; };
|
||||
7B1A6EF9149D148800FC5105 /* FiveByFive.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1A6EF8149D148800FC5105 /* FiveByFive.m */; };
|
||||
7B1A6EFC149D14C500FC5105 /* Show.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B1A6EFB149D14C500FC5105 /* Show.m */; };
|
||||
7B7302F2149D670A003547E5 /* GTMNSString+HTML.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7302EA149D670A003547E5 /* GTMNSString+HTML.h */; };
|
||||
7B7302F3149D670A003547E5 /* GTMNSString+HTML.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7302EB149D670A003547E5 /* GTMNSString+HTML.m */; };
|
||||
7B7302F4149D670A003547E5 /* NSDate+InternetDateTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7302EC149D670A003547E5 /* NSDate+InternetDateTime.h */; };
|
||||
7B7302F5149D670A003547E5 /* NSDate+InternetDateTime.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7302ED149D670A003547E5 /* NSDate+InternetDateTime.m */; };
|
||||
7B7302F6149D670A003547E5 /* NSString+HTML.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7302EE149D670A003547E5 /* NSString+HTML.h */; };
|
||||
7B7302F7149D670A003547E5 /* NSString+HTML.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7302EF149D670A003547E5 /* NSString+HTML.m */; };
|
||||
7B7302F8149D670A003547E5 /* NSString+XMLEntities.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7302F0149D670A003547E5 /* NSString+XMLEntities.h */; };
|
||||
7B7302F9149D670A003547E5 /* NSString+XMLEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7302F1149D670A003547E5 /* NSString+XMLEntities.m */; };
|
||||
7B730301149D6714003547E5 /* MWFeedInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7302FA149D6714003547E5 /* MWFeedInfo.h */; };
|
||||
7B730302149D6714003547E5 /* MWFeedInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7302FB149D6714003547E5 /* MWFeedInfo.m */; };
|
||||
7B730303149D6714003547E5 /* MWFeedItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7302FC149D6714003547E5 /* MWFeedItem.h */; };
|
||||
7B730304149D6714003547E5 /* MWFeedItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7302FD149D6714003547E5 /* MWFeedItem.m */; };
|
||||
7B730305149D6714003547E5 /* MWFeedParser_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7302FE149D6714003547E5 /* MWFeedParser_Private.h */; };
|
||||
7B730306149D6714003547E5 /* MWFeedParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7302FF149D6714003547E5 /* MWFeedParser.h */; };
|
||||
7B730307149D6714003547E5 /* MWFeedParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B730300149D6714003547E5 /* MWFeedParser.m */; };
|
||||
7B868946149D593C00F3A2C6 /* Episode.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B868945149D593C00F3A2C6 /* Episode.m */; };
|
||||
7B86894B149D5C1000F3A2C6 /* ShowViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B868949149D5C0F00F3A2C6 /* ShowViewController.m */; };
|
||||
7B868951149D5C6F00F3A2C6 /* ShowViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B86894D149D5C6F00F3A2C6 /* ShowViewController_iPad.xib */; };
|
||||
7B868952149D5C6F00F3A2C6 /* ShowViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B86894F149D5C6F00F3A2C6 /* ShowViewController_iPhone.xib */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
7B043E83149D6984004B52E8 /* back.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = back.png; sourceTree = "<group>"; };
|
||||
7B043E84149D6984004B52E8 /* back@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back@2x.png"; sourceTree = "<group>"; };
|
||||
7B043E85149D6984004B52E8 /* forw.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = forw.png; sourceTree = "<group>"; };
|
||||
7B043E86149D6984004B52E8 /* forw@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "forw@2x.png"; sourceTree = "<group>"; };
|
||||
7B043E8C149D6FA0004B52E8 /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
|
||||
7B043E8D149D6FA0004B52E8 /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = "<group>"; };
|
||||
7B1A6ECA149D140600FC5105 /* 5by5Browser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 5by5Browser.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7B1A6ECE149D140600FC5105 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
7B1A6ED0149D140600FC5105 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
7B1A6ED2149D140600FC5105 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
7B1A6ED6149D140600FC5105 /* 5by5Browser-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "5by5Browser-Info.plist"; sourceTree = "<group>"; };
|
||||
7B1A6ED8149D140600FC5105 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
7B1A6EDA149D140600FC5105 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
7B1A6EDC149D140600FC5105 /* 5by5Browser-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "5by5Browser-Prefix.pch"; sourceTree = "<group>"; };
|
||||
7B1A6EDD149D140600FC5105 /* SSAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSAppDelegate.h; sourceTree = "<group>"; };
|
||||
7B1A6EDE149D140600FC5105 /* SSAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SSAppDelegate.m; sourceTree = "<group>"; };
|
||||
7B1A6EE0149D140600FC5105 /* SSMasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSMasterViewController.h; sourceTree = "<group>"; };
|
||||
7B1A6EE1149D140600FC5105 /* SSMasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SSMasterViewController.m; sourceTree = "<group>"; };
|
||||
7B1A6EE3149D140600FC5105 /* SSDetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSDetailViewController.h; sourceTree = "<group>"; };
|
||||
7B1A6EE4149D140600FC5105 /* SSDetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SSDetailViewController.m; sourceTree = "<group>"; };
|
||||
7B1A6EE7149D140600FC5105 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/SSMasterViewController_iPhone.xib; sourceTree = "<group>"; };
|
||||
7B1A6EEA149D140600FC5105 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/SSMasterViewController_iPad.xib; sourceTree = "<group>"; };
|
||||
7B1A6EED149D140600FC5105 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/SSDetailViewController_iPhone.xib; sourceTree = "<group>"; };
|
||||
7B1A6EF0149D140600FC5105 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/SSDetailViewController_iPad.xib; sourceTree = "<group>"; };
|
||||
7B1A6EF7149D148800FC5105 /* FiveByFive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FiveByFive.h; sourceTree = "<group>"; };
|
||||
7B1A6EF8149D148800FC5105 /* FiveByFive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FiveByFive.m; sourceTree = "<group>"; };
|
||||
7B1A6EFA149D14C500FC5105 /* Show.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Show.h; sourceTree = "<group>"; };
|
||||
7B1A6EFB149D14C500FC5105 /* Show.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Show.m; sourceTree = "<group>"; };
|
||||
7B7302EA149D670A003547E5 /* GTMNSString+HTML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSString+HTML.h"; sourceTree = "<group>"; };
|
||||
7B7302EB149D670A003547E5 /* GTMNSString+HTML.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSString+HTML.m"; sourceTree = "<group>"; };
|
||||
7B7302EC149D670A003547E5 /* NSDate+InternetDateTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+InternetDateTime.h"; sourceTree = "<group>"; };
|
||||
7B7302ED149D670A003547E5 /* NSDate+InternetDateTime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+InternetDateTime.m"; sourceTree = "<group>"; };
|
||||
7B7302EE149D670A003547E5 /* NSString+HTML.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+HTML.h"; sourceTree = "<group>"; };
|
||||
7B7302EF149D670A003547E5 /* NSString+HTML.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+HTML.m"; sourceTree = "<group>"; };
|
||||
7B7302F0149D670A003547E5 /* NSString+XMLEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+XMLEntities.h"; sourceTree = "<group>"; };
|
||||
7B7302F1149D670A003547E5 /* NSString+XMLEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+XMLEntities.m"; sourceTree = "<group>"; };
|
||||
7B7302FA149D6714003547E5 /* MWFeedInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWFeedInfo.h; sourceTree = "<group>"; };
|
||||
7B7302FB149D6714003547E5 /* MWFeedInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWFeedInfo.m; sourceTree = "<group>"; };
|
||||
7B7302FC149D6714003547E5 /* MWFeedItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWFeedItem.h; sourceTree = "<group>"; };
|
||||
7B7302FD149D6714003547E5 /* MWFeedItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWFeedItem.m; sourceTree = "<group>"; };
|
||||
7B7302FE149D6714003547E5 /* MWFeedParser_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWFeedParser_Private.h; sourceTree = "<group>"; };
|
||||
7B7302FF149D6714003547E5 /* MWFeedParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MWFeedParser.h; sourceTree = "<group>"; };
|
||||
7B730300149D6714003547E5 /* MWFeedParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MWFeedParser.m; sourceTree = "<group>"; };
|
||||
7B868944149D593C00F3A2C6 /* Episode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Episode.h; sourceTree = "<group>"; };
|
||||
7B868945149D593C00F3A2C6 /* Episode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Episode.m; sourceTree = "<group>"; };
|
||||
7B868948149D5C0F00F3A2C6 /* ShowViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShowViewController.h; sourceTree = "<group>"; };
|
||||
7B868949149D5C0F00F3A2C6 /* ShowViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShowViewController.m; sourceTree = "<group>"; };
|
||||
7B86894E149D5C6F00F3A2C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ShowViewController_iPad.xib; sourceTree = "<group>"; };
|
||||
7B868950149D5C6F00F3A2C6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ShowViewController_iPhone.xib; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
7B1A6EC7149D140600FC5105 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7B1A6ECF149D140600FC5105 /* UIKit.framework in Frameworks */,
|
||||
7B1A6ED1149D140600FC5105 /* Foundation.framework in Frameworks */,
|
||||
7B1A6ED3149D140600FC5105 /* CoreGraphics.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
7B1A6EBF149D140600FC5105 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B7302E9149D66ED003547E5 /* MWFeedParser */,
|
||||
7B1A6ED4149D140600FC5105 /* 5by5Browser */,
|
||||
7B1A6ECD149D140600FC5105 /* Frameworks */,
|
||||
7B1A6ECB149D140600FC5105 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B1A6ECB149D140600FC5105 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B1A6ECA149D140600FC5105 /* 5by5Browser.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B1A6ECD149D140600FC5105 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B1A6ECE149D140600FC5105 /* UIKit.framework */,
|
||||
7B1A6ED0149D140600FC5105 /* Foundation.framework */,
|
||||
7B1A6ED2149D140600FC5105 /* CoreGraphics.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B1A6ED4149D140600FC5105 /* 5by5Browser */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B1A6EDD149D140600FC5105 /* SSAppDelegate.h */,
|
||||
7B1A6EDE149D140600FC5105 /* SSAppDelegate.m */,
|
||||
7B868948149D5C0F00F3A2C6 /* ShowViewController.h */,
|
||||
7B868949149D5C0F00F3A2C6 /* ShowViewController.m */,
|
||||
7B1A6EE0149D140600FC5105 /* SSMasterViewController.h */,
|
||||
7B1A6EE1149D140600FC5105 /* SSMasterViewController.m */,
|
||||
7B1A6EE3149D140600FC5105 /* SSDetailViewController.h */,
|
||||
7B1A6EE4149D140600FC5105 /* SSDetailViewController.m */,
|
||||
7B868944149D593C00F3A2C6 /* Episode.h */,
|
||||
7B868945149D593C00F3A2C6 /* Episode.m */,
|
||||
7B1A6EF7149D148800FC5105 /* FiveByFive.h */,
|
||||
7B1A6EF8149D148800FC5105 /* FiveByFive.m */,
|
||||
7B1A6EFA149D14C500FC5105 /* Show.h */,
|
||||
7B1A6EFB149D14C500FC5105 /* Show.m */,
|
||||
7B86894D149D5C6F00F3A2C6 /* ShowViewController_iPad.xib */,
|
||||
7B86894F149D5C6F00F3A2C6 /* ShowViewController_iPhone.xib */,
|
||||
7B1A6EE6149D140600FC5105 /* SSMasterViewController_iPhone.xib */,
|
||||
7B1A6EE9149D140600FC5105 /* SSMasterViewController_iPad.xib */,
|
||||
7B1A6EEC149D140600FC5105 /* SSDetailViewController_iPhone.xib */,
|
||||
7B1A6EEF149D140600FC5105 /* SSDetailViewController_iPad.xib */,
|
||||
7B1A6ED5149D140600FC5105 /* Supporting Files */,
|
||||
);
|
||||
path = 5by5Browser;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B1A6ED5149D140600FC5105 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B043E8C149D6FA0004B52E8 /* icon.png */,
|
||||
7B043E8D149D6FA0004B52E8 /* icon@2x.png */,
|
||||
7B043E83149D6984004B52E8 /* back.png */,
|
||||
7B043E84149D6984004B52E8 /* back@2x.png */,
|
||||
7B043E85149D6984004B52E8 /* forw.png */,
|
||||
7B043E86149D6984004B52E8 /* forw@2x.png */,
|
||||
7B1A6ED6149D140600FC5105 /* 5by5Browser-Info.plist */,
|
||||
7B1A6ED7149D140600FC5105 /* InfoPlist.strings */,
|
||||
7B1A6EDA149D140600FC5105 /* main.m */,
|
||||
7B1A6EDC149D140600FC5105 /* 5by5Browser-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B7302E7149D66EA003547E5 /* Categories */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B7302EA149D670A003547E5 /* GTMNSString+HTML.h */,
|
||||
7B7302EB149D670A003547E5 /* GTMNSString+HTML.m */,
|
||||
7B7302EC149D670A003547E5 /* NSDate+InternetDateTime.h */,
|
||||
7B7302ED149D670A003547E5 /* NSDate+InternetDateTime.m */,
|
||||
7B7302EE149D670A003547E5 /* NSString+HTML.h */,
|
||||
7B7302EF149D670A003547E5 /* NSString+HTML.m */,
|
||||
7B7302F0149D670A003547E5 /* NSString+XMLEntities.h */,
|
||||
7B7302F1149D670A003547E5 /* NSString+XMLEntities.m */,
|
||||
);
|
||||
name = Categories;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B7302E9149D66ED003547E5 /* MWFeedParser */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B7302E7149D66EA003547E5 /* Categories */,
|
||||
7B7302FA149D6714003547E5 /* MWFeedInfo.h */,
|
||||
7B7302FB149D6714003547E5 /* MWFeedInfo.m */,
|
||||
7B7302FC149D6714003547E5 /* MWFeedItem.h */,
|
||||
7B7302FD149D6714003547E5 /* MWFeedItem.m */,
|
||||
7B7302FE149D6714003547E5 /* MWFeedParser_Private.h */,
|
||||
7B7302FF149D6714003547E5 /* MWFeedParser.h */,
|
||||
7B730300149D6714003547E5 /* MWFeedParser.m */,
|
||||
);
|
||||
name = MWFeedParser;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
7B868976149D63B000F3A2C6 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7B7302F2149D670A003547E5 /* GTMNSString+HTML.h in Headers */,
|
||||
7B7302F4149D670A003547E5 /* NSDate+InternetDateTime.h in Headers */,
|
||||
7B7302F6149D670A003547E5 /* NSString+HTML.h in Headers */,
|
||||
7B7302F8149D670A003547E5 /* NSString+XMLEntities.h in Headers */,
|
||||
7B730301149D6714003547E5 /* MWFeedInfo.h in Headers */,
|
||||
7B730303149D6714003547E5 /* MWFeedItem.h in Headers */,
|
||||
7B730305149D6714003547E5 /* MWFeedParser_Private.h in Headers */,
|
||||
7B730306149D6714003547E5 /* MWFeedParser.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
7B1A6EC9149D140600FC5105 /* 5by5Browser */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 7B1A6EF4149D140600FC5105 /* Build configuration list for PBXNativeTarget "5by5Browser" */;
|
||||
buildPhases = (
|
||||
7B1A6EC6149D140600FC5105 /* Sources */,
|
||||
7B1A6EC7149D140600FC5105 /* Frameworks */,
|
||||
7B1A6EC8149D140600FC5105 /* Resources */,
|
||||
7B868976149D63B000F3A2C6 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = 5by5Browser;
|
||||
productName = 5by5Browser;
|
||||
productReference = 7B1A6ECA149D140600FC5105 /* 5by5Browser.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
7B1A6EC1149D140600FC5105 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
CLASSPREFIX = SS;
|
||||
LastUpgradeCheck = 0430;
|
||||
ORGANIZATIONNAME = "Guru Logic";
|
||||
};
|
||||
buildConfigurationList = 7B1A6EC4149D140600FC5105 /* Build configuration list for PBXProject "5by5Browser" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 7B1A6EBF149D140600FC5105;
|
||||
productRefGroup = 7B1A6ECB149D140600FC5105 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
7B1A6EC9149D140600FC5105 /* 5by5Browser */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
7B1A6EC8149D140600FC5105 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7B1A6ED9149D140600FC5105 /* InfoPlist.strings in Resources */,
|
||||
7B1A6EE8149D140600FC5105 /* SSMasterViewController_iPhone.xib in Resources */,
|
||||
7B1A6EEB149D140600FC5105 /* SSMasterViewController_iPad.xib in Resources */,
|
||||
7B1A6EEE149D140600FC5105 /* SSDetailViewController_iPhone.xib in Resources */,
|
||||
7B1A6EF1149D140600FC5105 /* SSDetailViewController_iPad.xib in Resources */,
|
||||
7B868951149D5C6F00F3A2C6 /* ShowViewController_iPad.xib in Resources */,
|
||||
7B868952149D5C6F00F3A2C6 /* ShowViewController_iPhone.xib in Resources */,
|
||||
7B043E87149D6984004B52E8 /* back.png in Resources */,
|
||||
7B043E88149D6984004B52E8 /* back@2x.png in Resources */,
|
||||
7B043E89149D6984004B52E8 /* forw.png in Resources */,
|
||||
7B043E8A149D6984004B52E8 /* forw@2x.png in Resources */,
|
||||
7B043E8E149D6FA0004B52E8 /* icon.png in Resources */,
|
||||
7B043E8F149D6FA0004B52E8 /* icon@2x.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
7B1A6EC6149D140600FC5105 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7B1A6EDB149D140600FC5105 /* main.m in Sources */,
|
||||
7B1A6EDF149D140600FC5105 /* SSAppDelegate.m in Sources */,
|
||||
7B1A6EE2149D140600FC5105 /* SSMasterViewController.m in Sources */,
|
||||
7B1A6EE5149D140600FC5105 /* SSDetailViewController.m in Sources */,
|
||||
7B1A6EF9149D148800FC5105 /* FiveByFive.m in Sources */,
|
||||
7B1A6EFC149D14C500FC5105 /* Show.m in Sources */,
|
||||
7B868946149D593C00F3A2C6 /* Episode.m in Sources */,
|
||||
7B86894B149D5C1000F3A2C6 /* ShowViewController.m in Sources */,
|
||||
7B7302F3149D670A003547E5 /* GTMNSString+HTML.m in Sources */,
|
||||
7B7302F5149D670A003547E5 /* NSDate+InternetDateTime.m in Sources */,
|
||||
7B7302F7149D670A003547E5 /* NSString+HTML.m in Sources */,
|
||||
7B7302F9149D670A003547E5 /* NSString+XMLEntities.m in Sources */,
|
||||
7B730302149D6714003547E5 /* MWFeedInfo.m in Sources */,
|
||||
7B730304149D6714003547E5 /* MWFeedItem.m in Sources */,
|
||||
7B730307149D6714003547E5 /* MWFeedParser.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
7B1A6ED7149D140600FC5105 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7B1A6ED8149D140600FC5105 /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B1A6EE6149D140600FC5105 /* SSMasterViewController_iPhone.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7B1A6EE7149D140600FC5105 /* en */,
|
||||
);
|
||||
name = SSMasterViewController_iPhone.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B1A6EE9149D140600FC5105 /* SSMasterViewController_iPad.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7B1A6EEA149D140600FC5105 /* en */,
|
||||
);
|
||||
name = SSMasterViewController_iPad.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B1A6EEC149D140600FC5105 /* SSDetailViewController_iPhone.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7B1A6EED149D140600FC5105 /* en */,
|
||||
);
|
||||
name = SSDetailViewController_iPhone.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B1A6EEF149D140600FC5105 /* SSDetailViewController_iPad.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7B1A6EF0149D140600FC5105 /* en */,
|
||||
);
|
||||
name = SSDetailViewController_iPad.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B86894D149D5C6F00F3A2C6 /* ShowViewController_iPad.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7B86894E149D5C6F00F3A2C6 /* en */,
|
||||
);
|
||||
name = ShowViewController_iPad.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B86894F149D5C6F00F3A2C6 /* ShowViewController_iPhone.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
7B868950149D5C6F00F3A2C6 /* en */,
|
||||
);
|
||||
name = ShowViewController_iPhone.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
7B1A6EF2149D140600FC5105 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
7B1A6EF3149D140600FC5105 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
||||
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
7B1A6EF5149D140600FC5105 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "5by5Browser/5by5Browser-Prefix.pch";
|
||||
INFOPLIST_FILE = "5by5Browser/5by5Browser-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
7B1A6EF6149D140600FC5105 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "5by5Browser/5by5Browser-Prefix.pch";
|
||||
INFOPLIST_FILE = "5by5Browser/5by5Browser-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 4.3;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
7B1A6EC4149D140600FC5105 /* Build configuration list for PBXProject "5by5Browser" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
7B1A6EF2149D140600FC5105 /* Debug */,
|
||||
7B1A6EF3149D140600FC5105 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
7B1A6EF4149D140600FC5105 /* Build configuration list for PBXNativeTarget "5by5Browser" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
7B1A6EF5149D140600FC5105 /* Debug */,
|
||||
7B1A6EF6149D140600FC5105 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 7B1A6EC1149D140600FC5105 /* Project object */;
|
||||
}
|
||||
7
5by5Browser.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
5by5Browser.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:5by5Browser.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
BIN
5by5Browser.xcodeproj/project.xcworkspace/xcuserdata/sjs.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
BIN
5by5Browser.xcodeproj/project.xcworkspace/xcuserdata/sjs.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
Binary file not shown.
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7B1A6EC9149D140600FC5105"
|
||||
BuildableName = "5by5Browser.app"
|
||||
BlueprintName = "5by5Browser"
|
||||
ReferencedContainer = "container:5by5Browser.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7B1A6EC9149D140600FC5105"
|
||||
BuildableName = "5by5Browser.app"
|
||||
BlueprintName = "5by5Browser"
|
||||
ReferencedContainer = "container:5by5Browser.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7B1A6EC9149D140600FC5105"
|
||||
BuildableName = "5by5Browser.app"
|
||||
BlueprintName = "5by5Browser"
|
||||
ReferencedContainer = "container:5by5Browser.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7B1A6EC9149D140600FC5105"
|
||||
BuildableName = "5by5Browser.app"
|
||||
BlueprintName = "5by5Browser"
|
||||
ReferencedContainer = "container:5by5Browser.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>5by5Browser.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>7B1A6EC9149D140600FC5105</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
46
5by5Browser/5by5Browser-Info.plist
Normal file
46
5by5Browser/5by5Browser-Info.plist
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>net.samhuri.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
14
5by5Browser/5by5Browser-Prefix.pch
Normal file
14
5by5Browser/5by5Browser-Prefix.pch
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// Prefix header for all source files of the '5by5Browser' target in the '5by5Browser' project
|
||||
//
|
||||
|
||||
#import <Availability.h>
|
||||
|
||||
#ifndef __IPHONE_4_0
|
||||
#warning "This project uses features only available in iOS SDK 4.0 and later."
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
||||
20
5by5Browser/Episode.h
Normal file
20
5by5Browser/Episode.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// Episode.h
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Episode : NSObject
|
||||
|
||||
@property (nonatomic, retain) NSString *name;
|
||||
@property (nonatomic, retain) NSString *number;
|
||||
@property (nonatomic, retain) NSURL *url;
|
||||
|
||||
+ (id) episodeWithName: (NSString *)name number: (NSString *)number url: (NSURL *)url;
|
||||
- (id) initWithName: (NSString *)name number: (NSString *)number url: (NSURL *)url;
|
||||
|
||||
@end
|
||||
33
5by5Browser/Episode.m
Normal file
33
5by5Browser/Episode.m
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// Episode.m
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Episode.h"
|
||||
|
||||
@implementation Episode
|
||||
|
||||
@synthesize name = _name;
|
||||
@synthesize number = _number;
|
||||
@synthesize url = _url;
|
||||
|
||||
+ (id) episodeWithName: (NSString *)name number: (NSString *)number url: (NSURL *)url
|
||||
{
|
||||
return [[self alloc] initWithName: name number: number url: url];
|
||||
}
|
||||
|
||||
- (id) initWithName: (NSString *)name number: (NSString *)number url: (NSURL *)url
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.name = name;
|
||||
self.number = number;
|
||||
self.url = url;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
21
5by5Browser/FiveByFive.h
Normal file
21
5by5Browser/FiveByFive.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// FiveByFive.h
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class Show;
|
||||
|
||||
@interface FiveByFive : NSObject
|
||||
|
||||
@property (nonatomic, retain) NSString *baseURL;
|
||||
@property (nonatomic, retain) NSMutableArray *shows;
|
||||
|
||||
- (id) initWithBaseURL: (NSString *)baseURL;
|
||||
- (void) addShow: (Show *)show;
|
||||
|
||||
@end
|
||||
33
5by5Browser/FiveByFive.m
Normal file
33
5by5Browser/FiveByFive.m
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// FiveByFive.m
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import "FiveByFive.h"
|
||||
#import "Show.h"
|
||||
|
||||
@implementation FiveByFive
|
||||
|
||||
@synthesize baseURL = _baseURL;
|
||||
@synthesize shows = _shows;
|
||||
|
||||
- (id) initWithBaseURL: (NSString *)baseURL
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.baseURL = baseURL;
|
||||
self.shows = [NSMutableArray array];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) addShow: (Show *)show
|
||||
{
|
||||
show.fiveByFive = self;
|
||||
[self.shows addObject: show];
|
||||
}
|
||||
|
||||
@end
|
||||
19
5by5Browser/SSAppDelegate.h
Normal file
19
5by5Browser/SSAppDelegate.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// SSAppDelegate.h
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface SSAppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
@property (strong, nonatomic) UINavigationController *navigationController;
|
||||
|
||||
@property (strong, nonatomic) UISplitViewController *splitViewController;
|
||||
|
||||
@end
|
||||
85
5by5Browser/SSAppDelegate.m
Normal file
85
5by5Browser/SSAppDelegate.m
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// SSAppDelegate.m
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SSAppDelegate.h"
|
||||
#import "SSMasterViewController.h"
|
||||
#import "SSDetailViewController.h"
|
||||
#import "FiveByFive.h"
|
||||
#import "Show.h"
|
||||
|
||||
@implementation SSAppDelegate
|
||||
|
||||
@synthesize window = _window;
|
||||
@synthesize navigationController = _navigationController;
|
||||
@synthesize splitViewController = _splitViewController;
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
|
||||
FiveByFive *fiveByFive = [[FiveByFive alloc] initWithBaseURL: @"http:/feeds.feedburner.com/"];
|
||||
[fiveByFive addShow: [Show showWithName: @"Back to Work" path: @"back2work"]];
|
||||
[fiveByFive addShow: [Show showWithName: @"Build and Analyze" path: @"buildanalyze"]];
|
||||
[fiveByFive addShow: [Show showWithName: @"Critical Path" path: @"criticalpath"]];
|
||||
[fiveByFive addShow: [Show showWithName: @"Geek Friday" path: @"GeekFriday"]];
|
||||
[fiveByFive addShow: [Show showWithName: @"Hypercritical" path: @"hypercritical"]];
|
||||
[fiveByFive addShow: [Show showWithName: @"The Talk Show" path: @"thetalkshow"]];
|
||||
|
||||
// Override point for customization after application launch.
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
SSMasterViewController *masterViewController = [[SSMasterViewController alloc] initWithNibName:@"SSMasterViewController_iPhone" bundle:nil];
|
||||
masterViewController.fiveByFive = fiveByFive;
|
||||
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
|
||||
self.window.rootViewController = self.navigationController;
|
||||
} else {
|
||||
SSMasterViewController *masterViewController = [[SSMasterViewController alloc] initWithNibName:@"SSMasterViewController_iPad" bundle:nil];
|
||||
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
|
||||
|
||||
SSDetailViewController *detailViewController = [[SSDetailViewController alloc] initWithNibName:@"SSDetailViewController_iPad" bundle:nil];
|
||||
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
|
||||
|
||||
masterViewController.fiveByFive = fiveByFive;
|
||||
|
||||
self.splitViewController = [[UISplitViewController alloc] init];
|
||||
self.splitViewController.delegate = detailViewController;
|
||||
self.splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavigationController, detailNavigationController, nil];
|
||||
|
||||
self.window.rootViewController = self.splitViewController;
|
||||
}
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
{
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
@end
|
||||
22
5by5Browser/SSDetailViewController.h
Normal file
22
5by5Browser/SSDetailViewController.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// SSDetailViewController.h
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "Episode.h"
|
||||
|
||||
@interface SSDetailViewController : UIViewController <UISplitViewControllerDelegate, UIWebViewDelegate>
|
||||
|
||||
@property (strong, nonatomic) Episode *episode;
|
||||
@property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
|
||||
@property (strong, nonatomic) IBOutlet UIWebView *webView;
|
||||
@property (strong, nonatomic) IBOutlet UIBarButtonItem *backButton;
|
||||
@property (strong, nonatomic) IBOutlet UIBarButtonItem *forwardButton;
|
||||
|
||||
- (IBAction) goHome;
|
||||
|
||||
@end
|
||||
107
5by5Browser/SSDetailViewController.m
Normal file
107
5by5Browser/SSDetailViewController.m
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
//
|
||||
// SSDetailViewController.m
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SSDetailViewController.h"
|
||||
|
||||
@interface SSDetailViewController ()
|
||||
@property (strong, nonatomic) UIPopoverController *masterPopoverController;
|
||||
- (void)configureView;
|
||||
@end
|
||||
|
||||
@implementation SSDetailViewController
|
||||
|
||||
@synthesize episode = _episode;
|
||||
@synthesize detailDescriptionLabel = _detailDescriptionLabel;
|
||||
@synthesize webView = _webView;
|
||||
@synthesize backButton = _backButton;
|
||||
@synthesize forwardButton = _forwardButton;
|
||||
@synthesize masterPopoverController = _masterPopoverController;
|
||||
|
||||
#pragma mark - Managing the detail item
|
||||
|
||||
- (void) setEpisode: (Episode *)episode
|
||||
{
|
||||
if (_episode != episode) {
|
||||
_episode = episode;
|
||||
|
||||
// Update the view.
|
||||
[self configureView];
|
||||
}
|
||||
|
||||
if (self.masterPopoverController != nil) {
|
||||
[self.masterPopoverController dismissPopoverAnimated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)configureView
|
||||
{
|
||||
// Update the user interface for the detail item.
|
||||
|
||||
if (self.episode) {
|
||||
self.title = self.episode.name;
|
||||
self.detailDescriptionLabel.text = self.episode.name;
|
||||
[self.webView loadRequest: [NSURLRequest requestWithURL: self.episode.url]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
[self configureView];
|
||||
}
|
||||
|
||||
- (void)viewDidUnload
|
||||
{
|
||||
[self setWebView:nil];
|
||||
[self setBackButton:nil];
|
||||
[self setForwardButton:nil];
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
self.detailDescriptionLabel = nil;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
|
||||
} else {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) webViewDidFinishLoad: (UIWebView *)webView
|
||||
{
|
||||
[self.backButton setEnabled: webView.canGoBack];
|
||||
[self.forwardButton setEnabled: webView.canGoForward];
|
||||
}
|
||||
|
||||
- (IBAction) goHome
|
||||
{
|
||||
while (self.webView.canGoBack) {
|
||||
[self.webView goBack];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Split view
|
||||
|
||||
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
|
||||
{
|
||||
barButtonItem.title = @"Shows";
|
||||
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
|
||||
self.masterPopoverController = popoverController;
|
||||
}
|
||||
|
||||
- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
|
||||
{
|
||||
// Called when the view is shown again in the split view, invalidating the button and popover controller.
|
||||
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
|
||||
self.masterPopoverController = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
17
5by5Browser/SSMasterViewController.h
Normal file
17
5by5Browser/SSMasterViewController.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// SSMasterViewController.h
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "FiveByFive.h"
|
||||
#import "Show.h"
|
||||
|
||||
@interface SSMasterViewController : UITableViewController <ShowDelegate>
|
||||
|
||||
@property (nonatomic, retain) FiveByFive *fiveByFive;
|
||||
|
||||
@end
|
||||
128
5by5Browser/SSMasterViewController.m
Normal file
128
5by5Browser/SSMasterViewController.m
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
//
|
||||
// SSMasterViewController.m
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SSMasterViewController.h"
|
||||
#import "ShowViewController.h"
|
||||
#import "Show.h"
|
||||
|
||||
@implementation SSMasterViewController
|
||||
|
||||
@synthesize fiveByFive = _fiveByFive;
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if (self) {
|
||||
self.title = @"5by5 Shows";
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
|
||||
self.clearsSelectionOnViewWillAppear = NO;
|
||||
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
}
|
||||
|
||||
- (void)viewDidUnload
|
||||
{
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
}
|
||||
|
||||
- (void) viewWillAppear: (BOOL)animated
|
||||
{
|
||||
[super viewWillAppear: animated];
|
||||
|
||||
for (int i = 0; i < [self tableView: self.tableView numberOfRowsInSection: 0]; ++i) {
|
||||
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow: i inSection: 0]];
|
||||
cell.accessoryView = nil;
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
}
|
||||
else {
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
|
||||
} else {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setFiveByFive: (FiveByFive *)fiveByFive
|
||||
{
|
||||
_fiveByFive = fiveByFive;
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
#pragma mark - Table View
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.fiveByFive.shows.count;
|
||||
}
|
||||
|
||||
// Customize the appearance of table view cells.
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
static NSString *CellIdentifier = @"Cell";
|
||||
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
|
||||
if (cell == nil) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
|
||||
}
|
||||
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
}
|
||||
else {
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
}
|
||||
|
||||
Show *show = [self.fiveByFive.shows objectAtIndex: indexPath.row];
|
||||
show.delegate = self;
|
||||
cell.textLabel.text = show.name;
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[[self.fiveByFive.shows objectAtIndex: indexPath.row] getEpisodes];
|
||||
UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray];
|
||||
[indicatorView startAnimating];
|
||||
[tableView cellForRowAtIndexPath: indexPath].accessoryView = indicatorView;
|
||||
}
|
||||
|
||||
- (void) gotEpisodesForShow: (Show *)show
|
||||
{
|
||||
ShowViewController *vc;
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
vc = [[ShowViewController alloc] initWithNibName: @"ShowViewController_iPhone" bundle: nil];
|
||||
}
|
||||
else {
|
||||
vc = [[ShowViewController alloc] initWithNibName: @"ShowViewController_iPad" bundle: nil];
|
||||
}
|
||||
vc.show = show;
|
||||
[self.navigationController pushViewController: vc animated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
31
5by5Browser/Show.h
Normal file
31
5by5Browser/Show.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// Show.h
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MWFeedParser.h"
|
||||
#import "Episode.h"
|
||||
#import "FiveByFive.h"
|
||||
|
||||
@protocol ShowDelegate <NSObject>
|
||||
- (void) gotEpisodesForShow: (Show *)show;
|
||||
@end
|
||||
|
||||
@interface Show : NSObject <MWFeedParserDelegate>
|
||||
|
||||
@property (nonatomic, assign) id<ShowDelegate> delegate;
|
||||
@property (nonatomic, retain) FiveByFive *fiveByFive;
|
||||
@property (nonatomic, retain) NSString *name;
|
||||
@property (nonatomic, retain) NSString *path;
|
||||
@property (nonatomic, retain) NSMutableArray *episodes;
|
||||
|
||||
+ (id) showWithName: (NSString *)name path: (NSString *)path;
|
||||
- (id) initWithName: (NSString *)name path: (NSString *)path;
|
||||
- (void) addEpisode: (Episode *)episode;
|
||||
- (void) getEpisodes;
|
||||
|
||||
@end
|
||||
95
5by5Browser/Show.m
Normal file
95
5by5Browser/Show.m
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// Show.m
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Show.h"
|
||||
#import "MWFeedParser.h"
|
||||
|
||||
// Private API
|
||||
@interface Show ()
|
||||
- (NSURL *) feedURL;
|
||||
@end
|
||||
|
||||
|
||||
@implementation Show
|
||||
|
||||
@synthesize delegate = _delegate;
|
||||
@synthesize fiveByFive = _fiveByFive;
|
||||
@synthesize name = _name;
|
||||
@synthesize path = _path;
|
||||
@synthesize episodes = _episodes;
|
||||
|
||||
+ (id) showWithName: (NSString *)name path: (NSString *)path
|
||||
{
|
||||
return [[self alloc] initWithName: name path: path];
|
||||
}
|
||||
|
||||
- (id) initWithName: (NSString *)name path: (NSString *)path
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.name = name;
|
||||
self.path = path;
|
||||
self.episodes = [NSMutableArray array];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) getEpisodes
|
||||
{
|
||||
if (self.episodes.count == 0) {
|
||||
MWFeedParser *parser = [[MWFeedParser alloc] initWithFeedURL: [self feedURL]];
|
||||
parser.delegate = self;
|
||||
parser.feedParseType = ParseTypeFull;
|
||||
parser.connectionType = ConnectionTypeAsynchronously;
|
||||
[parser parse];
|
||||
}
|
||||
else {
|
||||
[self.delegate gotEpisodesForShow: self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) addEpisode: (Episode *)episode
|
||||
{
|
||||
[self.episodes addObject: episode];
|
||||
}
|
||||
|
||||
- (NSURL *) feedURL
|
||||
{
|
||||
return [NSURL URLWithString: [[self.fiveByFive baseURL] stringByAppendingPathComponent: self.path]];
|
||||
}
|
||||
|
||||
|
||||
// MWFeedParserDelegate methods
|
||||
|
||||
- (void) feedParserDidStart: (MWFeedParser *)parser
|
||||
{
|
||||
NSLog(@"feed parser started");
|
||||
}
|
||||
|
||||
- (void) feedParser: (MWFeedParser *)parser didParseFeedInfo: (MWFeedInfo *)info
|
||||
{
|
||||
NSLog(@"feed info: %@", info);
|
||||
}
|
||||
|
||||
- (void) feedParser: (MWFeedParser *)parser didParseFeedItem: (MWFeedItem *)item
|
||||
{
|
||||
NSLog(@"feed item: %@", item);
|
||||
[self addEpisode: [Episode episodeWithName: item.title number: @"<n>" url: [NSURL URLWithString: item.link]]];
|
||||
}
|
||||
|
||||
- (void) feedParserDidFinish: (MWFeedParser *)parser
|
||||
{
|
||||
[self.delegate gotEpisodesForShow: self];
|
||||
}
|
||||
|
||||
- (void) feedParser: (MWFeedParser *)parser didFailWithError: (NSError *)error
|
||||
{
|
||||
NSLog(@"feed parser error: %@", error);
|
||||
}
|
||||
|
||||
@end
|
||||
18
5by5Browser/ShowViewController.h
Normal file
18
5by5Browser/ShowViewController.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// ShowViewController.h
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "SSDetailViewController.h"
|
||||
#import "Show.h"
|
||||
|
||||
@interface ShowViewController : UITableViewController
|
||||
|
||||
@property (strong, nonatomic) SSDetailViewController *detailViewController;
|
||||
@property (nonatomic, retain) Show *show;
|
||||
|
||||
@end
|
||||
101
5by5Browser/ShowViewController.m
Normal file
101
5by5Browser/ShowViewController.m
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
//
|
||||
// ShowViewController.m
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ShowViewController.h"
|
||||
#import "SSDetailViewController.h"
|
||||
#import "Episode.h"
|
||||
|
||||
@interface ShowViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation ShowViewController
|
||||
|
||||
@synthesize detailViewController = _detailViewController;
|
||||
@synthesize show = _show;
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if (self) {
|
||||
// Custom initialization
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view from its nib.
|
||||
}
|
||||
|
||||
- (void)viewDidUnload
|
||||
{
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
// e.g. self.myOutlet = nil;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
||||
}
|
||||
|
||||
- (void) setShow: (Show *)show
|
||||
{
|
||||
_show = show;
|
||||
self.title = self.show.name;
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
#pragma mark - Table View
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.show.episodes.count;
|
||||
}
|
||||
|
||||
// Customize the appearance of table view cells.
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
static NSString *CellIdentifier = @"Cell";
|
||||
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
|
||||
if (cell == nil) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Episode *episode = [self.show.episodes objectAtIndex: indexPath.row];
|
||||
cell.textLabel.text = episode.name;
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Episode *episode = [self.show.episodes objectAtIndex: indexPath.row];
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
if (!self.detailViewController) {
|
||||
self.detailViewController = [[SSDetailViewController alloc] initWithNibName: @"SSDetailViewController_iPhone" bundle: nil];
|
||||
}
|
||||
self.detailViewController.episode = episode;
|
||||
[self.navigationController pushViewController: self.detailViewController animated:YES];
|
||||
} else {
|
||||
self.detailViewController.episode = episode;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
BIN
5by5Browser/back.png
Normal file
BIN
5by5Browser/back.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3 KiB |
BIN
5by5Browser/back@2x.png
Normal file
BIN
5by5Browser/back@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
2
5by5Browser/en.lproj/InfoPlist.strings
Normal file
2
5by5Browser/en.lproj/InfoPlist.strings
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/* Localized versions of Info.plist keys */
|
||||
|
||||
177
5by5Browser/en.lproj/SSDetailViewController_iPad.xib
Normal file
177
5by5Browser/en.lproj/SSDetailViewController_iPad.xib
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1280</int>
|
||||
<string key="IBDocument.SystemVersion">11C74</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">2148</string>
|
||||
<string key="IBDocument.AppKitVersion">1138.23</string>
|
||||
<string key="IBDocument.HIToolboxVersion">567.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">1145</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBProxyObject</string>
|
||||
<string>IBUIView</string>
|
||||
<string>IBUIWebView</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="IBProxyObject" id="841351856">
|
||||
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
</object>
|
||||
<object class="IBProxyObject" id="606714003">
|
||||
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
</object>
|
||||
<object class="IBUIView" id="647120888">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="IBUIWebView" id="982214524">
|
||||
<reference key="NSNextResponder" ref="647120888"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrameSize">{768, 1004}</string>
|
||||
<reference key="NSSuperview" ref="647120888"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:693</string>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">1</int>
|
||||
<bytes key="NSRGB">MSAxIDEAA</bytes>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
<int key="IBUIDataDetectorTypes">1</int>
|
||||
<bool key="IBUIDetectsPhoneNumbers">YES</bool>
|
||||
</object>
|
||||
</array>
|
||||
<string key="NSFrame">{{0, 20}, {768, 1004}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="982214524"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
|
||||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
|
||||
<int key="IBUIStatusBarStyle">2</int>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
<reference key="source" ref="841351856"/>
|
||||
<reference key="destination" ref="647120888"/>
|
||||
</object>
|
||||
<int key="connectionID">12</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">webView</string>
|
||||
<reference key="source" ref="841351856"/>
|
||||
<reference key="destination" ref="982214524"/>
|
||||
</object>
|
||||
<int key="connectionID">69</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="982214524"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">68</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="841351856"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="606714003"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">8</int>
|
||||
<reference key="object" ref="647120888"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="982214524"/>
|
||||
</array>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">67</int>
|
||||
<reference key="object" ref="982214524"/>
|
||||
<reference key="parent" ref="647120888"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.CustomClassName">SSDetailViewController</string>
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="-2.CustomClassName">UIResponder</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="67.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="8.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">69</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">SSDetailViewController</string>
|
||||
<string key="superclassName">UIViewController</string>
|
||||
<dictionary class="NSMutableDictionary" key="outlets">
|
||||
<string key="detailDescriptionLabel">UILabel</string>
|
||||
<string key="webView">UIWebView</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<object class="IBToOneOutletInfo" key="detailDescriptionLabel">
|
||||
<string key="name">detailDescriptionLabel</string>
|
||||
<string key="candidateClassName">UILabel</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="webView">
|
||||
<string key="name">webView</string>
|
||||
<string key="candidateClassName">UIWebView</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/SSDetailViewController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">1145</string>
|
||||
</data>
|
||||
</archive>
|
||||
339
5by5Browser/en.lproj/SSDetailViewController_iPhone.xib
Normal file
339
5by5Browser/en.lproj/SSDetailViewController_iPhone.xib
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1280</int>
|
||||
<string key="IBDocument.SystemVersion">11C74</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">2148</string>
|
||||
<string key="IBDocument.AppKitVersion">1138.23</string>
|
||||
<string key="IBDocument.HIToolboxVersion">567.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">1145</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBUIWebView</string>
|
||||
<string>IBUIBarButtonItem</string>
|
||||
<string>IBUIToolbar</string>
|
||||
<string>IBUIView</string>
|
||||
<string>IBProxyObject</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="IBProxyObject" id="372490531">
|
||||
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBProxyObject" id="975951072">
|
||||
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBUIView" id="191373211">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="IBUIWebView" id="517643825">
|
||||
<reference key="NSNextResponder" ref="191373211"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrameSize">{320, 416}</string>
|
||||
<reference key="NSSuperview" ref="191373211"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="592752272"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:693</string>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">1</int>
|
||||
<bytes key="NSRGB">MSAxIDEAA</bytes>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBUIScalesPageToFit">YES</bool>
|
||||
<int key="IBUIDataDetectorTypes">1</int>
|
||||
<bool key="IBUIDetectsPhoneNumbers">YES</bool>
|
||||
</object>
|
||||
<object class="IBUIToolbar" id="592752272">
|
||||
<reference key="NSNextResponder" ref="191373211"/>
|
||||
<int key="NSvFlags">266</int>
|
||||
<string key="NSFrame">{{0, 416}, {320, 44}}</string>
|
||||
<reference key="NSSuperview" ref="191373211"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:371</string>
|
||||
<bool key="IBUIOpaque">NO</bool>
|
||||
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<array class="NSMutableArray" key="IBUIItems">
|
||||
<object class="IBUIBarButtonItem" id="1003054208">
|
||||
<bool key="IBUIEnabled">NO</bool>
|
||||
<object class="NSCustomResource" key="IBUIImage">
|
||||
<string key="NSClassName">NSImage</string>
|
||||
<string key="NSResourceName">back.png</string>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<reference key="IBUIToolbar" ref="592752272"/>
|
||||
</object>
|
||||
<object class="IBUIBarButtonItem" id="703595657">
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<reference key="IBUIToolbar" ref="592752272"/>
|
||||
<int key="IBUISystemItemIdentifier">5</int>
|
||||
</object>
|
||||
<object class="IBUIBarButtonItem" id="362932883">
|
||||
<string key="IBUITitle">Home</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<int key="IBUIStyle">1</int>
|
||||
<reference key="IBUIToolbar" ref="592752272"/>
|
||||
</object>
|
||||
<object class="IBUIBarButtonItem" id="8781673">
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<reference key="IBUIToolbar" ref="592752272"/>
|
||||
<int key="IBUISystemItemIdentifier">5</int>
|
||||
</object>
|
||||
<object class="IBUIBarButtonItem" id="604700786">
|
||||
<bool key="IBUIEnabled">NO</bool>
|
||||
<object class="NSCustomResource" key="IBUIImage">
|
||||
<string key="NSClassName">NSImage</string>
|
||||
<string key="NSResourceName">forw.png</string>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<reference key="IBUIToolbar" ref="592752272"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
</array>
|
||||
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView" ref="517643825"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
<object class="NSColorSpace" key="NSCustomColorSpace">
|
||||
<int key="NSID">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
<reference key="source" ref="372490531"/>
|
||||
<reference key="destination" ref="191373211"/>
|
||||
</object>
|
||||
<int key="connectionID">3</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">webView</string>
|
||||
<reference key="source" ref="372490531"/>
|
||||
<reference key="destination" ref="517643825"/>
|
||||
</object>
|
||||
<int key="connectionID">9</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">backButton</string>
|
||||
<reference key="source" ref="372490531"/>
|
||||
<reference key="destination" ref="1003054208"/>
|
||||
</object>
|
||||
<int key="connectionID">18</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">forwardButton</string>
|
||||
<reference key="source" ref="372490531"/>
|
||||
<reference key="destination" ref="604700786"/>
|
||||
</object>
|
||||
<int key="connectionID">19</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="517643825"/>
|
||||
<reference key="destination" ref="372490531"/>
|
||||
</object>
|
||||
<int key="connectionID">8</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">goBack</string>
|
||||
<reference key="source" ref="1003054208"/>
|
||||
<reference key="destination" ref="517643825"/>
|
||||
</object>
|
||||
<int key="connectionID">16</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">goForward</string>
|
||||
<reference key="source" ref="604700786"/>
|
||||
<reference key="destination" ref="517643825"/>
|
||||
</object>
|
||||
<int key="connectionID">17</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchEventConnection" key="connection">
|
||||
<string key="label">goHome</string>
|
||||
<reference key="source" ref="362932883"/>
|
||||
<reference key="destination" ref="372490531"/>
|
||||
</object>
|
||||
<int key="connectionID">20</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">1</int>
|
||||
<reference key="object" ref="191373211"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="517643825"/>
|
||||
<reference ref="592752272"/>
|
||||
</array>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="372490531"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="975951072"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">7</int>
|
||||
<reference key="object" ref="517643825"/>
|
||||
<reference key="parent" ref="191373211"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">10</int>
|
||||
<reference key="object" ref="592752272"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="1003054208"/>
|
||||
<reference ref="604700786"/>
|
||||
<reference ref="703595657"/>
|
||||
<reference ref="8781673"/>
|
||||
<reference ref="362932883"/>
|
||||
</array>
|
||||
<reference key="parent" ref="191373211"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">11</int>
|
||||
<reference key="object" ref="1003054208"/>
|
||||
<reference key="parent" ref="592752272"/>
|
||||
<string key="objectName">Bar Button Item - Back</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">12</int>
|
||||
<reference key="object" ref="604700786"/>
|
||||
<reference key="parent" ref="592752272"/>
|
||||
<string key="objectName">Bar Button Item - Forward</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">13</int>
|
||||
<reference key="object" ref="703595657"/>
|
||||
<reference key="parent" ref="592752272"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">14</int>
|
||||
<reference key="object" ref="8781673"/>
|
||||
<reference key="parent" ref="592752272"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">15</int>
|
||||
<reference key="object" ref="362932883"/>
|
||||
<reference key="parent" ref="592752272"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.CustomClassName">SSDetailViewController</string>
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="-2.CustomClassName">UIResponder</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="10.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="11.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="12.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="13.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="14.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="15.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">20</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">SSDetailViewController</string>
|
||||
<string key="superclassName">UIViewController</string>
|
||||
<object class="NSMutableDictionary" key="actions">
|
||||
<string key="NS.key.0">goHome</string>
|
||||
<string key="NS.object.0">id</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="actionInfosByName">
|
||||
<string key="NS.key.0">goHome</string>
|
||||
<object class="IBActionInfo" key="NS.object.0">
|
||||
<string key="name">goHome</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="outlets">
|
||||
<string key="backButton">UIBarButtonItem</string>
|
||||
<string key="detailDescriptionLabel">UILabel</string>
|
||||
<string key="forwardButton">UIBarButtonItem</string>
|
||||
<string key="webView">UIWebView</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<object class="IBToOneOutletInfo" key="backButton">
|
||||
<string key="name">backButton</string>
|
||||
<string key="candidateClassName">UIBarButtonItem</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="detailDescriptionLabel">
|
||||
<string key="name">detailDescriptionLabel</string>
|
||||
<string key="candidateClassName">UILabel</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="forwardButton">
|
||||
<string key="name">forwardButton</string>
|
||||
<string key="candidateClassName">UIBarButtonItem</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="webView">
|
||||
<string key="name">webView</string>
|
||||
<string key="candidateClassName">UIWebView</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/SSDetailViewController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
|
||||
<string key="back.png">{15, 18}</string>
|
||||
<string key="forw.png">{15, 18}</string>
|
||||
</dictionary>
|
||||
<string key="IBCocoaTouchPluginVersion">1145</string>
|
||||
</data>
|
||||
</archive>
|
||||
151
5by5Browser/en.lproj/SSMasterViewController_iPad.xib
Normal file
151
5by5Browser/en.lproj/SSMasterViewController_iPad.xib
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1280</int>
|
||||
<string key="IBDocument.SystemVersion">11C74</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">2148</string>
|
||||
<string key="IBDocument.AppKitVersion">1138.23</string>
|
||||
<string key="IBDocument.HIToolboxVersion">567.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">1145</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBProxyObject</string>
|
||||
<string>IBUITableView</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="IBProxyObject" id="841351856">
|
||||
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
</object>
|
||||
<object class="IBProxyObject" id="371349661">
|
||||
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
</object>
|
||||
<object class="IBUITableView" id="286511803">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrame">{{0, 20}, {320, 832}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
<bool key="IBUIClipsSubviews">YES</bool>
|
||||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
|
||||
<int key="IBUIStatusBarStyle">2</int>
|
||||
</object>
|
||||
<object class="IBUISimulatedSizeMetrics" key="IBUISimulatedDestinationMetrics">
|
||||
<string key="IBUISimulatedSizeMetricsClass">IBUISplitViewMasterSimulatedSizeMetrics</string>
|
||||
<object class="NSMutableDictionary" key="IBUINormalizedOrientationToSizeMap">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<array key="dict.sortedKeys">
|
||||
<integer value="1"/>
|
||||
<integer value="3"/>
|
||||
</array>
|
||||
<array key="dict.values">
|
||||
<string>{320, 852}</string>
|
||||
<string>{320, 768}</string>
|
||||
</array>
|
||||
</object>
|
||||
<string key="IBUITargetRuntime">IBIPadFramework</string>
|
||||
<string key="IBUIDisplayName">Master</string>
|
||||
<string key="IBUIDestinationClass">IBUISplitViewController</string>
|
||||
<object class="NSDictionary" key="IBUIDestinationContext">
|
||||
<string key="NS.key.0">IBUISplitViewControllerContentSizeLocation</string>
|
||||
<string key="NS.object.0">IBUISplitViewControllerContentSizeLocationMaster</string>
|
||||
</object>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
<bool key="IBUIAlwaysBounceVertical">YES</bool>
|
||||
<int key="IBUISeparatorStyle">1</int>
|
||||
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
|
||||
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
|
||||
<float key="IBUIRowHeight">44</float>
|
||||
<float key="IBUISectionHeaderHeight">22</float>
|
||||
<float key="IBUISectionFooterHeight">22</float>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
<reference key="source" ref="841351856"/>
|
||||
<reference key="destination" ref="286511803"/>
|
||||
</object>
|
||||
<int key="connectionID">3</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">dataSource</string>
|
||||
<reference key="source" ref="286511803"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">4</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="286511803"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">5</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="841351856"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="371349661"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">2</int>
|
||||
<reference key="object" ref="286511803"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.CustomClassName">ShowViewController</string>
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="-2.CustomClassName">UIResponder</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">5</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes"/>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">1145</string>
|
||||
</data>
|
||||
</archive>
|
||||
140
5by5Browser/en.lproj/SSMasterViewController_iPhone.xib
Normal file
140
5by5Browser/en.lproj/SSMasterViewController_iPhone.xib
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1280</int>
|
||||
<string key="IBDocument.SystemVersion">11C74</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">2148</string>
|
||||
<string key="IBDocument.AppKitVersion">1138.23</string>
|
||||
<string key="IBDocument.HIToolboxVersion">567.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">1145</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBProxyObject</string>
|
||||
<string>IBUITableView</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="IBProxyObject" id="841351856">
|
||||
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBProxyObject" id="371349661">
|
||||
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBUITableView" id="709618507">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
<bool key="IBUIClipsSubviews">YES</bool>
|
||||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBUIAlwaysBounceVertical">YES</bool>
|
||||
<int key="IBUISeparatorStyle">1</int>
|
||||
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
|
||||
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
|
||||
<float key="IBUIRowHeight">44</float>
|
||||
<float key="IBUISectionHeaderHeight">22</float>
|
||||
<float key="IBUISectionFooterHeight">22</float>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
<reference key="source" ref="841351856"/>
|
||||
<reference key="destination" ref="709618507"/>
|
||||
</object>
|
||||
<int key="connectionID">3</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">dataSource</string>
|
||||
<reference key="source" ref="709618507"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">4</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="709618507"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">5</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="841351856"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="371349661"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">2</int>
|
||||
<reference key="object" ref="709618507"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.CustomClassName">ShowViewController</string>
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="-2.CustomClassName">UIResponder</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">5</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">ShowViewController</string>
|
||||
<string key="superclassName">UIViewController</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/ShowViewController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">1145</string>
|
||||
</data>
|
||||
</archive>
|
||||
162
5by5Browser/en.lproj/ShowViewController_iPad.xib
Normal file
162
5by5Browser/en.lproj/ShowViewController_iPad.xib
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1280</int>
|
||||
<string key="IBDocument.SystemVersion">11C25</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">1919</string>
|
||||
<string key="IBDocument.AppKitVersion">1138.11</string>
|
||||
<string key="IBDocument.HIToolboxVersion">566.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">916</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBProxyObject</string>
|
||||
<string>IBUITableView</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="IBProxyObject" id="841351856">
|
||||
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
</object>
|
||||
<object class="IBProxyObject" id="371349661">
|
||||
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
</object>
|
||||
<object class="IBUITableView" id="286511803">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrame">{{0, 20}, {320, 832}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
<bool key="IBUIClipsSubviews">YES</bool>
|
||||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics">
|
||||
<int key="IBUIStatusBarStyle">2</int>
|
||||
</object>
|
||||
<object class="IBUISimulatedSizeMetrics" key="IBUISimulatedDestinationMetrics">
|
||||
<string key="IBUISimulatedSizeMetricsClass">IBUISplitViewMasterSimulatedSizeMetrics</string>
|
||||
<object class="NSMutableDictionary" key="IBUINormalizedOrientationToSizeMap">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<array key="dict.sortedKeys">
|
||||
<integer value="1"/>
|
||||
<integer value="3"/>
|
||||
</array>
|
||||
<array class="NSMutableArray" key="dict.values">
|
||||
<string>{320, 852}</string>
|
||||
<string>{320, 768}</string>
|
||||
</array>
|
||||
</object>
|
||||
<string key="IBUITargetRuntime">IBIPadFramework</string>
|
||||
<string key="IBUIDisplayName">Master</string>
|
||||
<string key="IBUIDestinationClass">IBUISplitViewController</string>
|
||||
<object class="NSDictionary" key="IBUIDestinationContext">
|
||||
<string key="NS.key.0">IBUISplitViewControllerContentSizeLocation</string>
|
||||
<string key="NS.object.0">IBUISplitViewControllerContentSizeLocationMaster</string>
|
||||
</object>
|
||||
</object>
|
||||
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
|
||||
<bool key="IBUIAlwaysBounceVertical">YES</bool>
|
||||
<int key="IBUISeparatorStyle">1</int>
|
||||
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
|
||||
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
|
||||
<float key="IBUIRowHeight">44</float>
|
||||
<float key="IBUISectionHeaderHeight">22</float>
|
||||
<float key="IBUISectionFooterHeight">22</float>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
<reference key="source" ref="841351856"/>
|
||||
<reference key="destination" ref="286511803"/>
|
||||
</object>
|
||||
<int key="connectionID">3</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">dataSource</string>
|
||||
<reference key="source" ref="286511803"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">4</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="286511803"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">5</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="841351856"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="371349661"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">2</int>
|
||||
<reference key="object" ref="286511803"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.CustomClassName">SSMasterViewController</string>
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="-2.CustomClassName">UIResponder</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">5</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">SSMasterViewController</string>
|
||||
<string key="superclassName">UITableViewController</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/SSMasterViewController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">916</string>
|
||||
</data>
|
||||
</archive>
|
||||
139
5by5Browser/en.lproj/ShowViewController_iPhone.xib
Normal file
139
5by5Browser/en.lproj/ShowViewController_iPhone.xib
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1280</int>
|
||||
<string key="IBDocument.SystemVersion">11C25</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">1919</string>
|
||||
<string key="IBDocument.AppKitVersion">1138.11</string>
|
||||
<string key="IBDocument.HIToolboxVersion">566.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">916</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBProxyObject</string>
|
||||
<string>IBUITableView</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="IBProxyObject" id="841351856">
|
||||
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBProxyObject" id="371349661">
|
||||
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBUITableView" id="709618507">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
<bool key="IBUIClipsSubviews">YES</bool>
|
||||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBUIAlwaysBounceVertical">YES</bool>
|
||||
<int key="IBUISeparatorStyle">1</int>
|
||||
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
|
||||
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
|
||||
<float key="IBUIRowHeight">44</float>
|
||||
<float key="IBUISectionHeaderHeight">22</float>
|
||||
<float key="IBUISectionFooterHeight">22</float>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
<reference key="source" ref="841351856"/>
|
||||
<reference key="destination" ref="709618507"/>
|
||||
</object>
|
||||
<int key="connectionID">3</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">dataSource</string>
|
||||
<reference key="source" ref="709618507"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">4</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="709618507"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">5</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="841351856"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="371349661"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">2</int>
|
||||
<reference key="object" ref="709618507"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.CustomClassName">SSMasterViewController</string>
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="-2.CustomClassName">UIResponder</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">5</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">SSMasterViewController</string>
|
||||
<string key="superclassName">UITableViewController</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/SSMasterViewController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">916</string>
|
||||
</data>
|
||||
</archive>
|
||||
BIN
5by5Browser/forw.png
Normal file
BIN
5by5Browser/forw.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
5by5Browser/forw@2x.png
Normal file
BIN
5by5Browser/forw@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3 KiB |
BIN
5by5Browser/icon.png
Normal file
BIN
5by5Browser/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
5by5Browser/icon@2x.png
Normal file
BIN
5by5Browser/icon@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
18
5by5Browser/main.m
Normal file
18
5by5Browser/main.m
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// main.m
|
||||
// 5by5Browser
|
||||
//
|
||||
// Created by Sami Samhuri on 11-12-17.
|
||||
// Copyright (c) 2011 Guru Logic. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "SSAppDelegate.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([SSAppDelegate class]));
|
||||
}
|
||||
}
|
||||
66
GTMNSString+HTML.h
Normal file
66
GTMNSString+HTML.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// GTMNSString+HTML.h
|
||||
// Dealing with NSStrings that contain HTML
|
||||
//
|
||||
// Copyright 2006-2008 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
// use this file except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/// Utilities for NSStrings containing HTML
|
||||
@interface NSString (GTMNSStringHTMLAdditions)
|
||||
|
||||
/// Get a string where internal characters that need escaping for HTML are escaped
|
||||
//
|
||||
/// For example, '&' become '&'. This will only cover characters from table
|
||||
/// A.2.2 of http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters
|
||||
/// which is what you want for a unicode encoded webpage. If you have a ascii
|
||||
/// or non-encoded webpage, please use stringByEscapingAsciiHTML which will
|
||||
/// encode all characters.
|
||||
///
|
||||
/// For obvious reasons this call is only safe once.
|
||||
//
|
||||
// Returns:
|
||||
// Autoreleased NSString
|
||||
//
|
||||
- (NSString *)gtm_stringByEscapingForHTML;
|
||||
|
||||
/// Get a string where internal characters that need escaping for HTML are escaped
|
||||
//
|
||||
/// For example, '&' become '&'
|
||||
/// All non-mapped characters (unicode that don't have a &keyword; mapping)
|
||||
/// will be converted to the appropriate &#xxx; value. If your webpage is
|
||||
/// unicode encoded (UTF16 or UTF8) use stringByEscapingHTML instead as it is
|
||||
/// faster, and produces less bloated and more readable HTML (as long as you
|
||||
/// are using a unicode compliant HTML reader).
|
||||
///
|
||||
/// For obvious reasons this call is only safe once.
|
||||
//
|
||||
// Returns:
|
||||
// Autoreleased NSString
|
||||
//
|
||||
- (NSString *)gtm_stringByEscapingForAsciiHTML;
|
||||
|
||||
/// Get a string where internal characters that are escaped for HTML are unescaped
|
||||
//
|
||||
/// For example, '&' becomes '&'
|
||||
/// Handles   and 2 cases as well
|
||||
///
|
||||
// Returns:
|
||||
// Autoreleased NSString
|
||||
//
|
||||
- (NSString *)gtm_stringByUnescapingFromHTML;
|
||||
|
||||
@end
|
||||
522
GTMNSString+HTML.m
Normal file
522
GTMNSString+HTML.m
Normal file
|
|
@ -0,0 +1,522 @@
|
|||
//
|
||||
// GTMNSString+HTML.m
|
||||
// Dealing with NSStrings that contain HTML
|
||||
//
|
||||
// Copyright 2006-2008 Google Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
// use this file except in compliance with the License. You may obtain a copy
|
||||
// of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations under
|
||||
// the License.
|
||||
//
|
||||
|
||||
//#import "GTMDefines.h"
|
||||
#import "GTMNSString+HTML.h"
|
||||
|
||||
typedef struct {
|
||||
__unsafe_unretained NSString *escapeSequence;
|
||||
unichar uchar;
|
||||
} HTMLEscapeMap;
|
||||
|
||||
// Taken from http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters
|
||||
// Ordered by uchar lowest to highest for bsearching
|
||||
static HTMLEscapeMap gAsciiHTMLEscapeMap[] = {
|
||||
// A.2.2. Special characters
|
||||
{ @""", 34 },
|
||||
{ @"&", 38 },
|
||||
{ @"'", 39 },
|
||||
{ @"<", 60 },
|
||||
{ @">", 62 },
|
||||
|
||||
// A.2.1. Latin-1 characters
|
||||
{ @" ", 160 },
|
||||
{ @"¡", 161 },
|
||||
{ @"¢", 162 },
|
||||
{ @"£", 163 },
|
||||
{ @"¤", 164 },
|
||||
{ @"¥", 165 },
|
||||
{ @"¦", 166 },
|
||||
{ @"§", 167 },
|
||||
{ @"¨", 168 },
|
||||
{ @"©", 169 },
|
||||
{ @"ª", 170 },
|
||||
{ @"«", 171 },
|
||||
{ @"¬", 172 },
|
||||
{ @"­", 173 },
|
||||
{ @"®", 174 },
|
||||
{ @"¯", 175 },
|
||||
{ @"°", 176 },
|
||||
{ @"±", 177 },
|
||||
{ @"²", 178 },
|
||||
{ @"³", 179 },
|
||||
{ @"´", 180 },
|
||||
{ @"µ", 181 },
|
||||
{ @"¶", 182 },
|
||||
{ @"·", 183 },
|
||||
{ @"¸", 184 },
|
||||
{ @"¹", 185 },
|
||||
{ @"º", 186 },
|
||||
{ @"»", 187 },
|
||||
{ @"¼", 188 },
|
||||
{ @"½", 189 },
|
||||
{ @"¾", 190 },
|
||||
{ @"¿", 191 },
|
||||
{ @"À", 192 },
|
||||
{ @"Á", 193 },
|
||||
{ @"Â", 194 },
|
||||
{ @"Ã", 195 },
|
||||
{ @"Ä", 196 },
|
||||
{ @"Å", 197 },
|
||||
{ @"Æ", 198 },
|
||||
{ @"Ç", 199 },
|
||||
{ @"È", 200 },
|
||||
{ @"É", 201 },
|
||||
{ @"Ê", 202 },
|
||||
{ @"Ë", 203 },
|
||||
{ @"Ì", 204 },
|
||||
{ @"Í", 205 },
|
||||
{ @"Î", 206 },
|
||||
{ @"Ï", 207 },
|
||||
{ @"Ð", 208 },
|
||||
{ @"Ñ", 209 },
|
||||
{ @"Ò", 210 },
|
||||
{ @"Ó", 211 },
|
||||
{ @"Ô", 212 },
|
||||
{ @"Õ", 213 },
|
||||
{ @"Ö", 214 },
|
||||
{ @"×", 215 },
|
||||
{ @"Ø", 216 },
|
||||
{ @"Ù", 217 },
|
||||
{ @"Ú", 218 },
|
||||
{ @"Û", 219 },
|
||||
{ @"Ü", 220 },
|
||||
{ @"Ý", 221 },
|
||||
{ @"Þ", 222 },
|
||||
{ @"ß", 223 },
|
||||
{ @"à", 224 },
|
||||
{ @"á", 225 },
|
||||
{ @"â", 226 },
|
||||
{ @"ã", 227 },
|
||||
{ @"ä", 228 },
|
||||
{ @"å", 229 },
|
||||
{ @"æ", 230 },
|
||||
{ @"ç", 231 },
|
||||
{ @"è", 232 },
|
||||
{ @"é", 233 },
|
||||
{ @"ê", 234 },
|
||||
{ @"ë", 235 },
|
||||
{ @"ì", 236 },
|
||||
{ @"í", 237 },
|
||||
{ @"î", 238 },
|
||||
{ @"ï", 239 },
|
||||
{ @"ð", 240 },
|
||||
{ @"ñ", 241 },
|
||||
{ @"ò", 242 },
|
||||
{ @"ó", 243 },
|
||||
{ @"ô", 244 },
|
||||
{ @"õ", 245 },
|
||||
{ @"ö", 246 },
|
||||
{ @"÷", 247 },
|
||||
{ @"ø", 248 },
|
||||
{ @"ù", 249 },
|
||||
{ @"ú", 250 },
|
||||
{ @"û", 251 },
|
||||
{ @"ü", 252 },
|
||||
{ @"ý", 253 },
|
||||
{ @"þ", 254 },
|
||||
{ @"ÿ", 255 },
|
||||
|
||||
// A.2.2. Special characters cont'd
|
||||
{ @"Œ", 338 },
|
||||
{ @"œ", 339 },
|
||||
{ @"Š", 352 },
|
||||
{ @"š", 353 },
|
||||
{ @"Ÿ", 376 },
|
||||
|
||||
// A.2.3. Symbols
|
||||
{ @"ƒ", 402 },
|
||||
|
||||
// A.2.2. Special characters cont'd
|
||||
{ @"ˆ", 710 },
|
||||
{ @"˜", 732 },
|
||||
|
||||
// A.2.3. Symbols cont'd
|
||||
{ @"Α", 913 },
|
||||
{ @"Β", 914 },
|
||||
{ @"Γ", 915 },
|
||||
{ @"Δ", 916 },
|
||||
{ @"Ε", 917 },
|
||||
{ @"Ζ", 918 },
|
||||
{ @"Η", 919 },
|
||||
{ @"Θ", 920 },
|
||||
{ @"Ι", 921 },
|
||||
{ @"Κ", 922 },
|
||||
{ @"Λ", 923 },
|
||||
{ @"Μ", 924 },
|
||||
{ @"Ν", 925 },
|
||||
{ @"Ξ", 926 },
|
||||
{ @"Ο", 927 },
|
||||
{ @"Π", 928 },
|
||||
{ @"Ρ", 929 },
|
||||
{ @"Σ", 931 },
|
||||
{ @"Τ", 932 },
|
||||
{ @"Υ", 933 },
|
||||
{ @"Φ", 934 },
|
||||
{ @"Χ", 935 },
|
||||
{ @"Ψ", 936 },
|
||||
{ @"Ω", 937 },
|
||||
{ @"α", 945 },
|
||||
{ @"β", 946 },
|
||||
{ @"γ", 947 },
|
||||
{ @"δ", 948 },
|
||||
{ @"ε", 949 },
|
||||
{ @"ζ", 950 },
|
||||
{ @"η", 951 },
|
||||
{ @"θ", 952 },
|
||||
{ @"ι", 953 },
|
||||
{ @"κ", 954 },
|
||||
{ @"λ", 955 },
|
||||
{ @"μ", 956 },
|
||||
{ @"ν", 957 },
|
||||
{ @"ξ", 958 },
|
||||
{ @"ο", 959 },
|
||||
{ @"π", 960 },
|
||||
{ @"ρ", 961 },
|
||||
{ @"ς", 962 },
|
||||
{ @"σ", 963 },
|
||||
{ @"τ", 964 },
|
||||
{ @"υ", 965 },
|
||||
{ @"φ", 966 },
|
||||
{ @"χ", 967 },
|
||||
{ @"ψ", 968 },
|
||||
{ @"ω", 969 },
|
||||
{ @"ϑ", 977 },
|
||||
{ @"ϒ", 978 },
|
||||
{ @"ϖ", 982 },
|
||||
|
||||
// A.2.2. Special characters cont'd
|
||||
{ @" ", 8194 },
|
||||
{ @" ", 8195 },
|
||||
{ @" ", 8201 },
|
||||
{ @"‌", 8204 },
|
||||
{ @"‍", 8205 },
|
||||
{ @"‎", 8206 },
|
||||
{ @"‏", 8207 },
|
||||
{ @"–", 8211 },
|
||||
{ @"—", 8212 },
|
||||
{ @"‘", 8216 },
|
||||
{ @"’", 8217 },
|
||||
{ @"‚", 8218 },
|
||||
{ @"“", 8220 },
|
||||
{ @"”", 8221 },
|
||||
{ @"„", 8222 },
|
||||
{ @"†", 8224 },
|
||||
{ @"‡", 8225 },
|
||||
// A.2.3. Symbols cont'd
|
||||
{ @"•", 8226 },
|
||||
{ @"…", 8230 },
|
||||
|
||||
// A.2.2. Special characters cont'd
|
||||
{ @"‰", 8240 },
|
||||
|
||||
// A.2.3. Symbols cont'd
|
||||
{ @"′", 8242 },
|
||||
{ @"″", 8243 },
|
||||
|
||||
// A.2.2. Special characters cont'd
|
||||
{ @"‹", 8249 },
|
||||
{ @"›", 8250 },
|
||||
|
||||
// A.2.3. Symbols cont'd
|
||||
{ @"‾", 8254 },
|
||||
{ @"⁄", 8260 },
|
||||
|
||||
// A.2.2. Special characters cont'd
|
||||
{ @"€", 8364 },
|
||||
|
||||
// A.2.3. Symbols cont'd
|
||||
{ @"ℑ", 8465 },
|
||||
{ @"℘", 8472 },
|
||||
{ @"ℜ", 8476 },
|
||||
{ @"™", 8482 },
|
||||
{ @"ℵ", 8501 },
|
||||
{ @"←", 8592 },
|
||||
{ @"↑", 8593 },
|
||||
{ @"→", 8594 },
|
||||
{ @"↓", 8595 },
|
||||
{ @"↔", 8596 },
|
||||
{ @"↵", 8629 },
|
||||
{ @"⇐", 8656 },
|
||||
{ @"⇑", 8657 },
|
||||
{ @"⇒", 8658 },
|
||||
{ @"⇓", 8659 },
|
||||
{ @"⇔", 8660 },
|
||||
{ @"∀", 8704 },
|
||||
{ @"∂", 8706 },
|
||||
{ @"∃", 8707 },
|
||||
{ @"∅", 8709 },
|
||||
{ @"∇", 8711 },
|
||||
{ @"∈", 8712 },
|
||||
{ @"∉", 8713 },
|
||||
{ @"∋", 8715 },
|
||||
{ @"∏", 8719 },
|
||||
{ @"∑", 8721 },
|
||||
{ @"−", 8722 },
|
||||
{ @"∗", 8727 },
|
||||
{ @"√", 8730 },
|
||||
{ @"∝", 8733 },
|
||||
{ @"∞", 8734 },
|
||||
{ @"∠", 8736 },
|
||||
{ @"∧", 8743 },
|
||||
{ @"∨", 8744 },
|
||||
{ @"∩", 8745 },
|
||||
{ @"∪", 8746 },
|
||||
{ @"∫", 8747 },
|
||||
{ @"∴", 8756 },
|
||||
{ @"∼", 8764 },
|
||||
{ @"≅", 8773 },
|
||||
{ @"≈", 8776 },
|
||||
{ @"≠", 8800 },
|
||||
{ @"≡", 8801 },
|
||||
{ @"≤", 8804 },
|
||||
{ @"≥", 8805 },
|
||||
{ @"⊂", 8834 },
|
||||
{ @"⊃", 8835 },
|
||||
{ @"⊄", 8836 },
|
||||
{ @"⊆", 8838 },
|
||||
{ @"⊇", 8839 },
|
||||
{ @"⊕", 8853 },
|
||||
{ @"⊗", 8855 },
|
||||
{ @"⊥", 8869 },
|
||||
{ @"⋅", 8901 },
|
||||
{ @"⌈", 8968 },
|
||||
{ @"⌉", 8969 },
|
||||
{ @"⌊", 8970 },
|
||||
{ @"⌋", 8971 },
|
||||
{ @"⟨", 9001 },
|
||||
{ @"⟩", 9002 },
|
||||
{ @"◊", 9674 },
|
||||
{ @"♠", 9824 },
|
||||
{ @"♣", 9827 },
|
||||
{ @"♥", 9829 },
|
||||
{ @"♦", 9830 }
|
||||
};
|
||||
|
||||
// Taken from http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters
|
||||
// This is table A.2.2 Special Characters
|
||||
static HTMLEscapeMap gUnicodeHTMLEscapeMap[] = {
|
||||
// C0 Controls and Basic Latin
|
||||
{ @""", 34 },
|
||||
{ @"&", 38 },
|
||||
{ @"'", 39 },
|
||||
{ @"<", 60 },
|
||||
{ @">", 62 },
|
||||
|
||||
// Latin Extended-A
|
||||
{ @"Œ", 338 },
|
||||
{ @"œ", 339 },
|
||||
{ @"Š", 352 },
|
||||
{ @"š", 353 },
|
||||
{ @"Ÿ", 376 },
|
||||
|
||||
// Spacing Modifier Letters
|
||||
{ @"ˆ", 710 },
|
||||
{ @"˜", 732 },
|
||||
|
||||
// General Punctuation
|
||||
{ @" ", 8194 },
|
||||
{ @" ", 8195 },
|
||||
{ @" ", 8201 },
|
||||
{ @"‌", 8204 },
|
||||
{ @"‍", 8205 },
|
||||
{ @"‎", 8206 },
|
||||
{ @"‏", 8207 },
|
||||
{ @"–", 8211 },
|
||||
{ @"—", 8212 },
|
||||
{ @"‘", 8216 },
|
||||
{ @"’", 8217 },
|
||||
{ @"‚", 8218 },
|
||||
{ @"“", 8220 },
|
||||
{ @"”", 8221 },
|
||||
{ @"„", 8222 },
|
||||
{ @"†", 8224 },
|
||||
{ @"‡", 8225 },
|
||||
{ @"‰", 8240 },
|
||||
{ @"‹", 8249 },
|
||||
{ @"›", 8250 },
|
||||
{ @"€", 8364 },
|
||||
};
|
||||
|
||||
|
||||
// Utility function for Bsearching table above
|
||||
static int EscapeMapCompare(const void *ucharVoid, const void *mapVoid) {
|
||||
const unichar *uchar = (const unichar*)ucharVoid;
|
||||
const HTMLEscapeMap *map = (const HTMLEscapeMap*)mapVoid;
|
||||
int val;
|
||||
if (*uchar > map->uchar) {
|
||||
val = 1;
|
||||
} else if (*uchar < map->uchar) {
|
||||
val = -1;
|
||||
} else {
|
||||
val = 0;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@implementation NSString (GTMNSStringHTMLAdditions)
|
||||
|
||||
- (NSString *)gtm_stringByEscapingHTMLUsingTable:(HTMLEscapeMap*)table
|
||||
ofSize:(NSUInteger)size
|
||||
escapingUnicode:(BOOL)escapeUnicode {
|
||||
NSUInteger length = [self length];
|
||||
if (!length) {
|
||||
return self;
|
||||
}
|
||||
|
||||
NSMutableString *finalString = [NSMutableString string];
|
||||
NSMutableData *data2 = [NSMutableData dataWithCapacity:sizeof(unichar) * length];
|
||||
|
||||
// this block is common between GTMNSString+HTML and GTMNSString+XML but
|
||||
// it's so short that it isn't really worth trying to share.
|
||||
const unichar *buffer = CFStringGetCharactersPtr((__bridge_retained CFStringRef)self);
|
||||
if (!buffer) {
|
||||
// We want this buffer to be autoreleased.
|
||||
NSMutableData *data = [NSMutableData dataWithLength:length * sizeof(UniChar)];
|
||||
if (!data) {
|
||||
// COV_NF_START - Memory fail case
|
||||
// _GTMDevLog(@"couldn't alloc buffer");
|
||||
return nil;
|
||||
// COV_NF_END
|
||||
}
|
||||
[self getCharacters:[data mutableBytes]];
|
||||
buffer = [data bytes];
|
||||
}
|
||||
|
||||
if (!buffer || !data2) {
|
||||
// COV_NF_START
|
||||
// _GTMDevLog(@"Unable to allocate buffer or data2");
|
||||
return nil;
|
||||
// COV_NF_END
|
||||
}
|
||||
|
||||
unichar *buffer2 = (unichar *)[data2 mutableBytes];
|
||||
|
||||
NSUInteger buffer2Length = 0;
|
||||
|
||||
for (NSUInteger i = 0; i < length; ++i) {
|
||||
HTMLEscapeMap *val = bsearch(&buffer[i], table,
|
||||
size / sizeof(HTMLEscapeMap),
|
||||
sizeof(HTMLEscapeMap), EscapeMapCompare);
|
||||
if (val || (escapeUnicode && buffer[i] > 127)) {
|
||||
if (buffer2Length) {
|
||||
CFStringAppendCharacters((__bridge_retained CFMutableStringRef)finalString,
|
||||
buffer2,
|
||||
buffer2Length);
|
||||
buffer2Length = 0;
|
||||
}
|
||||
if (val) {
|
||||
[finalString appendString:val->escapeSequence];
|
||||
}
|
||||
else {
|
||||
// _GTMDevAssert(escapeUnicode && buffer[i] > 127, @"Illegal Character");
|
||||
[finalString appendFormat:@"&#%d;", buffer[i]];
|
||||
}
|
||||
} else {
|
||||
buffer2[buffer2Length] = buffer[i];
|
||||
buffer2Length += 1;
|
||||
}
|
||||
}
|
||||
if (buffer2Length) {
|
||||
CFStringAppendCharacters((__bridge_retained CFMutableStringRef)finalString,
|
||||
buffer2,
|
||||
buffer2Length);
|
||||
}
|
||||
return finalString;
|
||||
}
|
||||
|
||||
- (NSString *)gtm_stringByEscapingForHTML {
|
||||
return [self gtm_stringByEscapingHTMLUsingTable:gUnicodeHTMLEscapeMap
|
||||
ofSize:sizeof(gUnicodeHTMLEscapeMap)
|
||||
escapingUnicode:NO];
|
||||
} // gtm_stringByEscapingHTML
|
||||
|
||||
- (NSString *)gtm_stringByEscapingForAsciiHTML {
|
||||
return [self gtm_stringByEscapingHTMLUsingTable:gAsciiHTMLEscapeMap
|
||||
ofSize:sizeof(gAsciiHTMLEscapeMap)
|
||||
escapingUnicode:YES];
|
||||
} // gtm_stringByEscapingAsciiHTML
|
||||
|
||||
- (NSString *)gtm_stringByUnescapingFromHTML {
|
||||
NSRange range = NSMakeRange(0, [self length]);
|
||||
NSRange subrange = [self rangeOfString:@"&" options:NSBackwardsSearch range:range];
|
||||
|
||||
// if no ampersands, we've got a quick way out
|
||||
if (subrange.length == 0) return self;
|
||||
NSMutableString *finalString = [NSMutableString stringWithString:self];
|
||||
do {
|
||||
NSRange semiColonRange = NSMakeRange(subrange.location, NSMaxRange(range) - subrange.location);
|
||||
semiColonRange = [self rangeOfString:@";" options:0 range:semiColonRange];
|
||||
range = NSMakeRange(0, subrange.location);
|
||||
// if we don't find a semicolon in the range, we don't have a sequence
|
||||
if (semiColonRange.location == NSNotFound) {
|
||||
continue;
|
||||
}
|
||||
NSRange escapeRange = NSMakeRange(subrange.location, semiColonRange.location - subrange.location + 1);
|
||||
NSString *escapeString = [self substringWithRange:escapeRange];
|
||||
NSUInteger length = [escapeString length];
|
||||
// a squence must be longer than 3 (<) and less than 11 (ϑ)
|
||||
if (length > 3 && length < 11) {
|
||||
if ([escapeString characterAtIndex:1] == '#') {
|
||||
unichar char2 = [escapeString characterAtIndex:2];
|
||||
if (char2 == 'x' || char2 == 'X') {
|
||||
// Hex escape squences £
|
||||
NSString *hexSequence = [escapeString substringWithRange:NSMakeRange(3, length - 4)];
|
||||
NSScanner *scanner = [NSScanner scannerWithString:hexSequence];
|
||||
unsigned value;
|
||||
if ([scanner scanHexInt:&value] &&
|
||||
value < USHRT_MAX &&
|
||||
value > 0
|
||||
&& [scanner scanLocation] == length - 4) {
|
||||
unichar uchar = value;
|
||||
NSString *charString = [NSString stringWithCharacters:&uchar length:1];
|
||||
[finalString replaceCharactersInRange:escapeRange withString:charString];
|
||||
}
|
||||
|
||||
} else {
|
||||
// Decimal Sequences {
|
||||
NSString *numberSequence = [escapeString substringWithRange:NSMakeRange(2, length - 3)];
|
||||
NSScanner *scanner = [NSScanner scannerWithString:numberSequence];
|
||||
int value;
|
||||
if ([scanner scanInt:&value] &&
|
||||
value < USHRT_MAX &&
|
||||
value > 0
|
||||
&& [scanner scanLocation] == length - 3) {
|
||||
unichar uchar = value;
|
||||
NSString *charString = [NSString stringWithCharacters:&uchar length:1];
|
||||
[finalString replaceCharactersInRange:escapeRange withString:charString];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// "standard" sequences
|
||||
for (unsigned i = 0; i < sizeof(gAsciiHTMLEscapeMap) / sizeof(HTMLEscapeMap); ++i) {
|
||||
if ([escapeString isEqualToString:gAsciiHTMLEscapeMap[i].escapeSequence]) {
|
||||
[finalString replaceCharactersInRange:escapeRange withString:[NSString stringWithCharacters:&gAsciiHTMLEscapeMap[i].uchar length:1]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((subrange = [self rangeOfString:@"&" options:NSBackwardsSearch range:range]).length != 0);
|
||||
return finalString;
|
||||
} // gtm_stringByUnescapingHTML
|
||||
|
||||
|
||||
|
||||
@end
|
||||
44
MWFeedInfo.h
Normal file
44
MWFeedInfo.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// MWFeedInfo.h
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MWFeedInfo : NSObject <NSCoding> {
|
||||
|
||||
NSString *title; // Feed title
|
||||
NSString *link; // Feed link
|
||||
NSString *summary; // Feed summary / description
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
@property (nonatomic, copy) NSString *link;
|
||||
@property (nonatomic, copy) NSString *summary;
|
||||
|
||||
@end
|
||||
66
MWFeedInfo.m
Normal file
66
MWFeedInfo.m
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// MWFeedInfo.m
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "MWFeedInfo.h"
|
||||
|
||||
#define EXCERPT(str, len) (([str length] > len) ? [[str substringToIndex:len-1] stringByAppendingString:@"…"] : str)
|
||||
|
||||
@implementation MWFeedInfo
|
||||
|
||||
@synthesize title, link, summary;
|
||||
|
||||
#pragma mark NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
NSMutableString *string = [[NSMutableString alloc] initWithString:@"MWFeedInfo: "];
|
||||
if (title) [string appendFormat:@"“%@”", EXCERPT(title, 50)];
|
||||
//if (link) [string appendFormat:@" (%@)", link];
|
||||
//if (summary) [string appendFormat:@", %@", MWExcerpt(summary, 50)];
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark NSCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
if ((self = [super init])) {
|
||||
title = [decoder decodeObjectForKey:@"title"];
|
||||
link = [decoder decodeObjectForKey:@"link"];
|
||||
summary = [decoder decodeObjectForKey:@"summary"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder {
|
||||
if (title) [encoder encodeObject:title forKey:@"title"];
|
||||
if (link) [encoder encodeObject:link forKey:@"link"];
|
||||
if (summary) [encoder encodeObject:summary forKey:@"summary"];
|
||||
}
|
||||
|
||||
@end
|
||||
60
MWFeedItem.h
Normal file
60
MWFeedItem.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// MWFeedItem.h
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MWFeedItem : NSObject <NSCoding> {
|
||||
|
||||
NSString *identifier; // Item identifier
|
||||
NSString *title; // Item title
|
||||
NSString *link; // Item URL
|
||||
NSDate *date; // Date the item was published
|
||||
NSDate *updated; // Date the item was updated if available
|
||||
NSString *summary; // Description of item
|
||||
NSString *content; // More detailed content (if available)
|
||||
|
||||
// Enclosures: Holds 1 or more item enclosures (i.e. podcasts, mp3. pdf, etc)
|
||||
// - NSArray of NSDictionaries with the following keys:
|
||||
// url: where the enclosure is located (NSString)
|
||||
// length: how big it is in bytes (NSNumber)
|
||||
// type: what its type is, a standard MIME type (NSString)
|
||||
NSArray *enclosures;
|
||||
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSString *identifier;
|
||||
@property (nonatomic, copy) NSString *title;
|
||||
@property (nonatomic, copy) NSString *link;
|
||||
@property (nonatomic, copy) NSDate *date;
|
||||
@property (nonatomic, copy) NSDate *updated;
|
||||
@property (nonatomic, copy) NSString *summary;
|
||||
@property (nonatomic, copy) NSString *content;
|
||||
@property (nonatomic, copy) NSArray *enclosures;
|
||||
|
||||
@end
|
||||
76
MWFeedItem.m
Normal file
76
MWFeedItem.m
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
//
|
||||
// MWFeedItem.m
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "MWFeedItem.h"
|
||||
|
||||
#define EXCERPT(str, len) (([str length] > len) ? [[str substringToIndex:len-1] stringByAppendingString:@"…"] : str)
|
||||
|
||||
@implementation MWFeedItem
|
||||
|
||||
@synthesize identifier, title, link, date, updated, summary, content, enclosures;
|
||||
|
||||
#pragma mark NSObject
|
||||
|
||||
- (NSString *)description {
|
||||
NSMutableString *string = [[NSMutableString alloc] initWithString:@"MWFeedItem: "];
|
||||
if (title) [string appendFormat:@"“%@”", EXCERPT(title, 50)];
|
||||
if (date) [string appendFormat:@" - %@", date];
|
||||
//if (link) [string appendFormat:@" (%@)", link];
|
||||
//if (summary) [string appendFormat:@", %@", EXCERPT(summary, 50)];
|
||||
return string ;
|
||||
}
|
||||
|
||||
#pragma mark NSCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder {
|
||||
if ((self = [super init])) {
|
||||
identifier = [decoder decodeObjectForKey:@"identifier"];
|
||||
title = [decoder decodeObjectForKey:@"title"];
|
||||
link = [decoder decodeObjectForKey:@"link"];
|
||||
date = [decoder decodeObjectForKey:@"date"];
|
||||
updated = [decoder decodeObjectForKey:@"updated"];
|
||||
summary = [decoder decodeObjectForKey:@"summary"];
|
||||
content = [decoder decodeObjectForKey:@"content"];
|
||||
enclosures = [decoder decodeObjectForKey:@"enclosures"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder {
|
||||
if (identifier) [encoder encodeObject:identifier forKey:@"identifier"];
|
||||
if (title) [encoder encodeObject:title forKey:@"title"];
|
||||
if (link) [encoder encodeObject:link forKey:@"link"];
|
||||
if (date) [encoder encodeObject:date forKey:@"date"];
|
||||
if (updated) [encoder encodeObject:updated forKey:@"updated"];
|
||||
if (summary) [encoder encodeObject:summary forKey:@"summary"];
|
||||
if (content) [encoder encodeObject:content forKey:@"content"];
|
||||
if (enclosures) [encoder encodeObject:enclosures forKey:@"enclosures"];
|
||||
}
|
||||
|
||||
@end
|
||||
143
MWFeedParser.h
Normal file
143
MWFeedParser.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
//
|
||||
// MWFeedParser.h
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MWFeedInfo.h"
|
||||
#import "MWFeedItem.h"
|
||||
|
||||
// Debug Logging
|
||||
#if 0 // Set to 1 to enable debug logging
|
||||
#define MWLog(x, ...) NSLog(x, ## __VA_ARGS__);
|
||||
#else
|
||||
#define MWLog(x, ...)
|
||||
#endif
|
||||
|
||||
// Errors & codes
|
||||
#define MWErrorDomain @"MWFeedParser"
|
||||
#define MWErrorCodeNotInitiated 1 /* MWFeedParser not initialised correctly */
|
||||
#define MWErrorCodeConnectionFailed 2 /* Connection to the URL failed */
|
||||
#define MWErrorCodeFeedParsingError 3 /* NSXMLParser encountered a parsing error */
|
||||
#define MWErrorCodeFeedValidationError 4 /* NSXMLParser encountered a validation error */
|
||||
#define MWErrorCodeGeneral 5 /* MWFeedParser general error */
|
||||
|
||||
// Class
|
||||
@class MWFeedParser;
|
||||
|
||||
// Types
|
||||
typedef enum { ConnectionTypeAsynchronously, ConnectionTypeSynchronously } ConnectionType;
|
||||
typedef enum { ParseTypeFull, ParseTypeItemsOnly, ParseTypeInfoOnly } ParseType;
|
||||
typedef enum { FeedTypeUnknown, FeedTypeRSS, FeedTypeRSS1, FeedTypeAtom } FeedType;
|
||||
|
||||
// Delegate
|
||||
@protocol MWFeedParserDelegate <NSObject>
|
||||
@optional
|
||||
- (void)feedParserDidStart:(MWFeedParser *)parser;
|
||||
- (void)feedParser:(MWFeedParser *)parser didParseFeedInfo:(MWFeedInfo *)info;
|
||||
- (void)feedParser:(MWFeedParser *)parser didParseFeedItem:(MWFeedItem *)item;
|
||||
- (void)feedParserDidFinish:(MWFeedParser *)parser;
|
||||
- (void)feedParser:(MWFeedParser *)parser didFailWithError:(NSError *)error;
|
||||
@end
|
||||
|
||||
// MWFeedParser
|
||||
@interface MWFeedParser : NSObject <NSXMLParserDelegate> {
|
||||
|
||||
@private
|
||||
|
||||
// Required
|
||||
//id <MWFeedParserDelegate> delegate;
|
||||
|
||||
// Connection
|
||||
NSURLConnection *urlConnection;
|
||||
NSMutableData *asyncData;
|
||||
NSString *asyncTextEncodingName;
|
||||
ConnectionType connectionType;
|
||||
|
||||
// Parsing
|
||||
ParseType feedParseType;
|
||||
NSXMLParser *feedParser;
|
||||
FeedType feedType;
|
||||
NSDateFormatter *dateFormatterRFC822, *dateFormatterRFC3339;
|
||||
|
||||
// Parsing State
|
||||
NSURL *url;
|
||||
BOOL aborted; // Whether parse stopped due to abort
|
||||
BOOL parsing; // Whether the MWFeedParser has started parsing
|
||||
BOOL stopped; // Whether the parse was stopped
|
||||
BOOL failed; // Whether the parse failed
|
||||
BOOL parsingComplete; // Whether NSXMLParser parsing has completed
|
||||
BOOL hasEncounteredItems; // Whether the parser has started parsing items
|
||||
|
||||
// Parsing of XML structure as content
|
||||
NSString *pathOfElementWithXHTMLType; // Hold the path of the element who's type="xhtml" so we can stop parsing when it's ended
|
||||
BOOL parseStructureAsContent; // For atom feeds when element type="xhtml"
|
||||
|
||||
// Parsing Data
|
||||
NSString *currentPath;
|
||||
NSMutableString *currentText;
|
||||
NSDictionary *currentElementAttributes;
|
||||
MWFeedItem *item;
|
||||
MWFeedInfo *info;
|
||||
|
||||
}
|
||||
|
||||
#pragma mark Public Properties
|
||||
|
||||
// Delegate to recieve data as it is parsed
|
||||
@property (nonatomic, assign) id <MWFeedParserDelegate> delegate;
|
||||
|
||||
// Whether to parse feed info & all items, just feed info, or just feed items
|
||||
@property (nonatomic) ParseType feedParseType;
|
||||
|
||||
// Set whether to download asynchronously or synchronously
|
||||
@property (nonatomic) ConnectionType connectionType;
|
||||
|
||||
// Whether parsing was stopped
|
||||
@property (nonatomic, readonly, getter=isStopped) BOOL stopped;
|
||||
|
||||
// Whether parsing failed
|
||||
@property (nonatomic, readonly, getter=didFail) BOOL failed;
|
||||
|
||||
// Whether parsing is in progress
|
||||
@property (nonatomic, readonly, getter=isParsing) BOOL parsing;
|
||||
|
||||
#pragma mark Public Methods
|
||||
|
||||
// Init MWFeedParser with a URL string
|
||||
- (id)initWithFeedURL:(NSURL *)feedURL;
|
||||
|
||||
// Begin parsing
|
||||
- (BOOL)parse;
|
||||
|
||||
// Stop parsing
|
||||
- (void)stopParsing;
|
||||
|
||||
// Returns the URL
|
||||
- (NSURL *)url;
|
||||
|
||||
@end
|
||||
935
MWFeedParser.m
Normal file
935
MWFeedParser.m
Normal file
|
|
@ -0,0 +1,935 @@
|
|||
//
|
||||
// MWFeedParser.m
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "MWFeedParser.h"
|
||||
#import "MWFeedParser_Private.h"
|
||||
#import "NSString+HTML.h"
|
||||
#import "NSDate+InternetDateTime.h"
|
||||
|
||||
// NSXMLParser Logging
|
||||
#if 0 // Set to 1 to enable XML parsing logs
|
||||
#define MWXMLLog(x, ...) NSLog(x, ## __VA_ARGS__);
|
||||
#else
|
||||
#define MWXMLLog(x, ...)
|
||||
#endif
|
||||
|
||||
// Empty XHTML elements ( <!ELEMENT br EMPTY> in http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd )
|
||||
#define ELEMENT_IS_EMPTY(e) ([e isEqualToString:@"br"] || [e isEqualToString:@"img"] || [e isEqualToString:@"input"] || \
|
||||
[e isEqualToString:@"hr"] || [e isEqualToString:@"link"] || [e isEqualToString:@"base"] || \
|
||||
[e isEqualToString:@"basefont"] || [e isEqualToString:@"frame"] || [e isEqualToString:@"meta"] || \
|
||||
[e isEqualToString:@"area"] || [e isEqualToString:@"col"] || [e isEqualToString:@"param"])
|
||||
|
||||
// Implementation
|
||||
@implementation MWFeedParser
|
||||
|
||||
// Properties
|
||||
@synthesize url, delegate;
|
||||
@synthesize urlConnection, asyncData, asyncTextEncodingName, connectionType;
|
||||
@synthesize feedParseType, feedParser, currentPath, currentText, currentElementAttributes, item, info;
|
||||
@synthesize pathOfElementWithXHTMLType;
|
||||
@synthesize stopped, failed, parsing;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark NSObject
|
||||
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
|
||||
// Defaults
|
||||
feedParseType = ParseTypeFull;
|
||||
connectionType = ConnectionTypeSynchronously;
|
||||
|
||||
// Date Formatters
|
||||
// Good info on internet dates here: http://developer.apple.com/iphone/library/qa/qa2010/qa1480.html
|
||||
NSLocale *en_US_POSIX = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
|
||||
dateFormatterRFC822 = [[NSDateFormatter alloc] init];
|
||||
dateFormatterRFC3339 = [[NSDateFormatter alloc] init];
|
||||
[dateFormatterRFC822 setLocale:en_US_POSIX];
|
||||
[dateFormatterRFC3339 setLocale:en_US_POSIX];
|
||||
[dateFormatterRFC822 setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
|
||||
[dateFormatterRFC3339 setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// Initialise with a URL
|
||||
// Mainly for historic reasons before -parseURL:
|
||||
- (id)initWithFeedURL:(NSURL *)feedURL {
|
||||
if ((self = [self init])) {
|
||||
|
||||
// Check if an string was passed as old init asked for NSString not NSURL
|
||||
if ([feedURL isKindOfClass:[NSString class]]) {
|
||||
feedURL = [NSURL URLWithString:(NSString *)feedURL];
|
||||
}
|
||||
|
||||
// Remember url
|
||||
self.url = feedURL;
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Parsing
|
||||
|
||||
// Reset data variables before processing
|
||||
// Exclude parse state variables as they are needed after parse
|
||||
- (void)reset {
|
||||
self.asyncData = nil;
|
||||
self.asyncTextEncodingName = nil;
|
||||
self.urlConnection = nil;
|
||||
feedType = FeedTypeUnknown;
|
||||
self.currentPath = @"/";
|
||||
self.currentText = [[NSMutableString alloc] init];
|
||||
self.item = nil;
|
||||
self.info = nil;
|
||||
self.currentElementAttributes = nil;
|
||||
parseStructureAsContent = NO;
|
||||
self.pathOfElementWithXHTMLType = nil;
|
||||
hasEncounteredItems = NO;
|
||||
}
|
||||
|
||||
// Parse using URL for backwards compatibility
|
||||
- (BOOL)parse {
|
||||
|
||||
// Reset
|
||||
[self reset];
|
||||
|
||||
// Perform checks before parsing
|
||||
if (!url || !delegate) { [self parsingFailedWithErrorCode:MWErrorCodeNotInitiated
|
||||
andDescription:@"Delegate or URL not specified"]; return NO; }
|
||||
if (parsing) { [self parsingFailedWithErrorCode:MWErrorCodeGeneral
|
||||
andDescription:@"Cannot start parsing as parsing is already in progress"]; return NO; }
|
||||
|
||||
// Reset state for next parse
|
||||
parsing = YES;
|
||||
aborted = NO;
|
||||
stopped = NO;
|
||||
failed = NO;
|
||||
parsingComplete = NO;
|
||||
|
||||
// Start
|
||||
BOOL success = YES;
|
||||
|
||||
// Request
|
||||
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url
|
||||
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
|
||||
timeoutInterval:60];
|
||||
[request setValue:@"MWFeedParser" forHTTPHeaderField:@"User-Agent"];
|
||||
|
||||
// Debug Log
|
||||
MWLog(@"MWFeedParser: Connecting & downloading feed data");
|
||||
|
||||
// Connection
|
||||
if (connectionType == ConnectionTypeAsynchronously) {
|
||||
|
||||
// Async
|
||||
urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
|
||||
if (urlConnection) {
|
||||
asyncData = [[NSMutableData alloc] init];// Create data
|
||||
} else {
|
||||
[self parsingFailedWithErrorCode:MWErrorCodeConnectionFailed
|
||||
andDescription:[NSString stringWithFormat:@"Asynchronous connection failed to URL: %@", url]];
|
||||
success = NO;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Sync
|
||||
NSURLResponse *response = nil;
|
||||
NSError *error = nil;
|
||||
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
|
||||
if (data && !error) {
|
||||
[self startParsingData:data textEncodingName:[response textEncodingName]]; // Process
|
||||
} else {
|
||||
[self parsingFailedWithErrorCode:MWErrorCodeConnectionFailed
|
||||
andDescription:[NSString stringWithFormat:@"Synchronous connection failed to URL: %@", url]];
|
||||
success = NO;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// return
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
// Begin XML parsing
|
||||
- (void)startParsingData:(NSData *)data textEncodingName:(NSString *)textEncodingName {
|
||||
if (data && !feedParser) {
|
||||
|
||||
// Create feed info
|
||||
MWFeedInfo *i = [[MWFeedInfo alloc] init];
|
||||
self.info = i;
|
||||
|
||||
// Check whether it's UTF-8
|
||||
if (![[textEncodingName lowercaseString] isEqualToString:@"utf-8"]) {
|
||||
|
||||
// Not UTF-8 so convert
|
||||
MWLog(@"MWFeedParser: XML document was not UTF-8 so we're converting it");
|
||||
NSString *string = nil;
|
||||
|
||||
// Attempt to detect encoding from response header
|
||||
NSStringEncoding nsEncoding = 0;
|
||||
if (textEncodingName) {
|
||||
CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((__bridge_retained CFStringRef)textEncodingName);
|
||||
if (cfEncoding != kCFStringEncodingInvalidId) {
|
||||
nsEncoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding);
|
||||
if (nsEncoding != 0) string = [[NSString alloc] initWithData:data encoding:nsEncoding];
|
||||
}
|
||||
}
|
||||
|
||||
// If that failed then make our own attempts
|
||||
if (!string) {
|
||||
// http://www.mikeash.com/pyblog/friday-qa-2010-02-19-character-encodings.html
|
||||
string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
if (!string) string = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
|
||||
if (!string) string = [[NSString alloc] initWithData:data encoding:NSMacOSRomanStringEncoding];
|
||||
}
|
||||
|
||||
// Nil data
|
||||
data = nil;
|
||||
|
||||
// Parse
|
||||
if (string) {
|
||||
|
||||
// Set XML encoding to UTF-8
|
||||
if ([string hasPrefix:@"<?xml"]) {
|
||||
NSRange a = [string rangeOfString:@"?>"];
|
||||
if (a.location != NSNotFound) {
|
||||
NSString *xmlDec = [string substringToIndex:a.location];
|
||||
if ([xmlDec rangeOfString:@"encoding=\"UTF-8\""
|
||||
options:NSCaseInsensitiveSearch].location == NSNotFound) {
|
||||
NSRange b = [xmlDec rangeOfString:@"encoding=\""];
|
||||
if (b.location != NSNotFound) {
|
||||
NSUInteger s = b.location+b.length;
|
||||
NSRange c = [xmlDec rangeOfString:@"\"" options:0 range:NSMakeRange(s, [xmlDec length] - s)];
|
||||
if (c.location != NSNotFound) {
|
||||
NSString *temp = [string stringByReplacingCharactersInRange:NSMakeRange(b.location,c.location+c.length-b.location)
|
||||
withString:@"encoding=\"UTF-8\""];
|
||||
string = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert string to UTF-8 data
|
||||
if (string) {
|
||||
data = [string dataUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create NSXMLParser
|
||||
if (data) {
|
||||
NSXMLParser *newFeedParser = [[NSXMLParser alloc] initWithData:data];
|
||||
self.feedParser = newFeedParser;
|
||||
if (feedParser) {
|
||||
|
||||
// Parse!
|
||||
feedParser.delegate = self;
|
||||
[feedParser setShouldProcessNamespaces:YES];
|
||||
[feedParser parse];
|
||||
self.feedParser = nil; // Release after parse
|
||||
|
||||
} else {
|
||||
[self parsingFailedWithErrorCode:MWErrorCodeFeedParsingError andDescription:@"Feed not a valid XML document"];
|
||||
}
|
||||
} else {
|
||||
[self parsingFailedWithErrorCode:MWErrorCodeFeedParsingError andDescription:@"Error with feed encoding"];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Abort parsing early if we're ignoring feed items
|
||||
- (void)abortParsingEarly {
|
||||
|
||||
// Abort
|
||||
aborted = YES; [feedParser abortParsing];
|
||||
[self parsingFinished];
|
||||
|
||||
}
|
||||
|
||||
// Stop parsing
|
||||
- (void)stopParsing {
|
||||
|
||||
// Only if we're parsing
|
||||
if (parsing && !parsingComplete) {
|
||||
|
||||
// Debug Log
|
||||
MWLog(@"MWFeedParser: Parsing stopped");
|
||||
|
||||
// Stop
|
||||
stopped = YES;
|
||||
|
||||
// Stop downloading
|
||||
[urlConnection cancel];
|
||||
self.urlConnection = nil;
|
||||
self.asyncData = nil;
|
||||
self.asyncTextEncodingName = nil;
|
||||
|
||||
// Abort
|
||||
aborted = YES;
|
||||
[feedParser abortParsing];
|
||||
|
||||
// Finished
|
||||
[self parsingFinished];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Finished parsing document successfully
|
||||
- (void)parsingFinished {
|
||||
|
||||
// Finish
|
||||
if (!parsingComplete) {
|
||||
|
||||
// Set state and notify delegate
|
||||
parsing = NO;
|
||||
parsingComplete = YES;
|
||||
if ([delegate respondsToSelector:@selector(feedParserDidFinish:)])
|
||||
[delegate feedParserDidFinish:self];
|
||||
|
||||
// Reset
|
||||
[self reset];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If an error occurs, create NSError and inform delegate
|
||||
- (void)parsingFailedWithErrorCode:(int)code andDescription:(NSString *)description {
|
||||
|
||||
// Finish & create error
|
||||
if (!parsingComplete) {
|
||||
|
||||
// State
|
||||
failed = YES;
|
||||
parsing = NO;
|
||||
parsingComplete = YES;
|
||||
|
||||
// Create error
|
||||
NSError *error = [NSError errorWithDomain:MWErrorDomain
|
||||
code:code
|
||||
userInfo:[NSDictionary dictionaryWithObject:description
|
||||
forKey:NSLocalizedDescriptionKey]];
|
||||
MWLog(@"%@", error);
|
||||
|
||||
// Abort parsing
|
||||
if (feedParser) {
|
||||
aborted = YES;
|
||||
[feedParser abortParsing];
|
||||
}
|
||||
|
||||
// Reset
|
||||
[self reset];
|
||||
|
||||
// Inform delegate
|
||||
if ([delegate respondsToSelector:@selector(feedParser:didFailWithError:)])
|
||||
[delegate feedParser:self didFailWithError:error];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark NSURLConnection Delegate (Async)
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
||||
[asyncData setLength:0];
|
||||
self.asyncTextEncodingName = [response textEncodingName];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
[asyncData appendData:data];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
||||
|
||||
// Failed
|
||||
self.urlConnection = nil;
|
||||
self.asyncData = nil;
|
||||
self.asyncTextEncodingName = nil;
|
||||
|
||||
// Error
|
||||
[self parsingFailedWithErrorCode:MWErrorCodeConnectionFailed andDescription:[error localizedDescription]];
|
||||
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
|
||||
// Succeed
|
||||
MWLog(@"MWFeedParser: Connection successful... received %d bytes of data", [asyncData length]);
|
||||
|
||||
// Parse
|
||||
if (!stopped) [self startParsingData:asyncData textEncodingName:self.asyncTextEncodingName];
|
||||
|
||||
// Cleanup
|
||||
self.urlConnection = nil;
|
||||
self.asyncData = nil;
|
||||
self.asyncTextEncodingName = nil;
|
||||
|
||||
}
|
||||
|
||||
-(NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
|
||||
return nil; // Don't cache
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark XML Parsing
|
||||
|
||||
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
|
||||
qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
|
||||
MWXMLLog(@"NSXMLParser: didStartElement: %@", qualifiedName);
|
||||
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
// Adjust path
|
||||
self.currentPath = [currentPath stringByAppendingPathComponent:qualifiedName];
|
||||
self.currentElementAttributes = attributeDict;
|
||||
|
||||
// Parse content as structure (Atom feeds with element type="xhtml")
|
||||
// - Use elementName not qualifiedName to ignore XML namespaces for XHTML entities
|
||||
if (parseStructureAsContent) {
|
||||
|
||||
// Open XHTML tag
|
||||
[currentText appendFormat:@"<%@", elementName];
|
||||
|
||||
// Add attributes
|
||||
for (NSString *key in attributeDict) {
|
||||
[currentText appendFormat:@" %@=\"%@\"", key,
|
||||
[[attributeDict objectForKey:key] stringByEncodingHTMLEntities]];
|
||||
}
|
||||
|
||||
// End tag or close
|
||||
if (ELEMENT_IS_EMPTY(elementName)) {
|
||||
[currentText appendFormat:@" />", elementName];
|
||||
} else {
|
||||
[currentText appendFormat:@">", elementName];
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Reset
|
||||
[self.currentText setString:@""];
|
||||
|
||||
// Determine feed type
|
||||
if (feedType == FeedTypeUnknown) {
|
||||
if ([qualifiedName isEqualToString:@"rss"]) feedType = FeedTypeRSS;
|
||||
else if ([qualifiedName isEqualToString:@"rdf:RDF"]) feedType = FeedTypeRSS1;
|
||||
else if ([qualifiedName isEqualToString:@"feed"]) feedType = FeedTypeAtom;
|
||||
else {
|
||||
|
||||
// Invalid format so fail
|
||||
[self parsingFailedWithErrorCode:MWErrorCodeFeedParsingError
|
||||
andDescription:@"XML document is not a valid web feed document."];
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Entering new feed element
|
||||
if (feedParseType != ParseTypeItemsOnly) {
|
||||
if ((feedType == FeedTypeRSS && [currentPath isEqualToString:@"/rss/channel"]) ||
|
||||
(feedType == FeedTypeRSS1 && [currentPath isEqualToString:@"/rdf:RDF/channel"]) ||
|
||||
(feedType == FeedTypeAtom && [currentPath isEqualToString:@"/feed"])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Entering new item element
|
||||
if ((feedType == FeedTypeRSS && [currentPath isEqualToString:@"/rss/channel/item"]) ||
|
||||
(feedType == FeedTypeRSS1 && [currentPath isEqualToString:@"/rdf:RDF/item"]) ||
|
||||
(feedType == FeedTypeAtom && [currentPath isEqualToString:@"/feed/entry"])) {
|
||||
|
||||
// Send off feed info to delegate
|
||||
if (!hasEncounteredItems) {
|
||||
hasEncounteredItems = YES;
|
||||
if (feedParseType != ParseTypeItemsOnly) { // Check whether to ignore feed info
|
||||
|
||||
// Dispatch feed info to delegate
|
||||
[self dispatchFeedInfoToDelegate];
|
||||
|
||||
// Stop parsing if only requiring meta data
|
||||
if (feedParseType == ParseTypeInfoOnly) {
|
||||
|
||||
// Debug log
|
||||
MWLog(@"MWFeedParser: Parse type is ParseTypeInfoOnly so finishing here");
|
||||
|
||||
// Finish
|
||||
[self abortParsingEarly];
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Ignoring feed info so debug log
|
||||
MWLog(@"MWFeedParser: Parse type is ParseTypeItemsOnly so ignoring feed info");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// New item
|
||||
MWFeedItem *newItem = [[MWFeedItem alloc] init];
|
||||
self.item = newItem;
|
||||
|
||||
|
||||
|
||||
// Return
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Check if entering into an Atom content tag with type "xhtml"
|
||||
// If type is "xhtml" then it can contain child elements and structure needs
|
||||
// to be parsed as content
|
||||
// See: http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1.1
|
||||
if (feedType == FeedTypeAtom) {
|
||||
|
||||
// Check type attribute
|
||||
NSString *typeAttribute = [attributeDict objectForKey:@"type"];
|
||||
if (typeAttribute && [typeAttribute isEqualToString:@"xhtml"]) {
|
||||
|
||||
// Start parsing structure as content
|
||||
parseStructureAsContent = YES;
|
||||
|
||||
// Remember path so we can stop parsing structure when element ends
|
||||
self.pathOfElementWithXHTMLType = currentPath;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
|
||||
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
|
||||
MWXMLLog(@"NSXMLParser: didEndElement: %@", qName);
|
||||
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
// Parse content as structure (Atom feeds with element type="xhtml")
|
||||
// - Use elementName not qualifiedName to ignore XML namespaces for XHTML entities
|
||||
if (parseStructureAsContent) {
|
||||
|
||||
// Check for finishing parsing structure as content
|
||||
if (currentPath.length > pathOfElementWithXHTMLType.length) {
|
||||
|
||||
// Close XHTML tag unless it is an empty element
|
||||
if (!ELEMENT_IS_EMPTY(elementName)) [currentText appendFormat:@"</%@>", elementName];
|
||||
|
||||
// Adjust path & don't continue
|
||||
self.currentPath = [currentPath stringByDeletingLastPathComponent];
|
||||
|
||||
// Return
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Finish
|
||||
parseStructureAsContent = NO;
|
||||
self.pathOfElementWithXHTMLType = nil;
|
||||
|
||||
// Continue...
|
||||
|
||||
}
|
||||
|
||||
// Store data
|
||||
BOOL processed = NO;
|
||||
if (currentText) {
|
||||
|
||||
// Remove newlines and whitespace from currentText
|
||||
NSString *processedText = [currentText stringByRemovingNewLinesAndWhitespace];
|
||||
|
||||
// Process
|
||||
switch (feedType) {
|
||||
case FeedTypeRSS: {
|
||||
|
||||
// Item
|
||||
if (!processed) {
|
||||
if ([currentPath isEqualToString:@"/rss/channel/item/title"]) { if (processedText.length > 0) item.title = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/item/link"]) { if (processedText.length > 0) item.link = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/item/guid"]) { if (processedText.length > 0) item.identifier = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/item/description"]) { if (processedText.length > 0) item.summary = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/item/content:encoded"]) { if (processedText.length > 0) item.content = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/item/pubDate"]) { if (processedText.length > 0) item.date = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC822]; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/item/enclosure"]) { [self createEnclosureFromAttributes:currentElementAttributes andAddToItem:item]; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/item/dc:date"]) { if (processedText.length > 0) item.date = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC3339]; processed = YES; }
|
||||
}
|
||||
|
||||
// Info
|
||||
if (!processed && feedParseType != ParseTypeItemsOnly) {
|
||||
if ([currentPath isEqualToString:@"/rss/channel/title"]) { if (processedText.length > 0) info.title = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/description"]) { if (processedText.length > 0) info.summary = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rss/channel/link"]) { if (processedText.length > 0) info.link = processedText; processed = YES; }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case FeedTypeRSS1: {
|
||||
|
||||
// Item
|
||||
if (!processed) {
|
||||
if ([currentPath isEqualToString:@"/rdf:RDF/item/title"]) { if (processedText.length > 0) item.title = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rdf:RDF/item/link"]) { if (processedText.length > 0) item.link = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rdf:RDF/item/dc:identifier"]) { if (processedText.length > 0) item.identifier = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rdf:RDF/item/description"]) { if (processedText.length > 0) item.summary = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rdf:RDF/item/content:encoded"]) { if (processedText.length > 0) item.content = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rdf:RDF/item/dc:date"]) { if (processedText.length > 0) item.date = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC3339]; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rdf:RDF/item/enc:enclosure"]) { [self createEnclosureFromAttributes:currentElementAttributes andAddToItem:item]; processed = YES; }
|
||||
}
|
||||
|
||||
// Info
|
||||
if (!processed && feedParseType != ParseTypeItemsOnly) {
|
||||
if ([currentPath isEqualToString:@"/rdf:RDF/channel/title"]) { if (processedText.length > 0) info.title = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rdf:RDF/channel/description"]) { if (processedText.length > 0) info.summary = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/rdf:RDF/channel/link"]) { if (processedText.length > 0) info.link = processedText; processed = YES; }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case FeedTypeAtom: {
|
||||
|
||||
// Item
|
||||
if (!processed) {
|
||||
if ([currentPath isEqualToString:@"/feed/entry/title"]) { if (processedText.length > 0) item.title = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/feed/entry/link"]) { [self processAtomLink:currentElementAttributes andAddToMWObject:item]; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/feed/entry/id"]) { if (processedText.length > 0) item.identifier = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/feed/entry/summary"]) { if (processedText.length > 0) item.summary = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/feed/entry/content"]) { if (processedText.length > 0) item.content = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/feed/entry/published"]) { if (processedText.length > 0) item.date = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC3339]; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/feed/entry/updated"]) { if (processedText.length > 0) item.updated = [NSDate dateFromInternetDateTimeString:processedText formatHint:DateFormatHintRFC3339]; processed = YES; }
|
||||
}
|
||||
|
||||
// Info
|
||||
if (!processed && feedParseType != ParseTypeItemsOnly) {
|
||||
if ([currentPath isEqualToString:@"/feed/title"]) { if (processedText.length > 0) info.title = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/feed/description"]) { if (processedText.length > 0) info.summary = processedText; processed = YES; }
|
||||
else if ([currentPath isEqualToString:@"/feed/link"]) { [self processAtomLink:currentElementAttributes andAddToMWObject:info]; processed = YES;}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust path
|
||||
self.currentPath = [currentPath stringByDeletingLastPathComponent];
|
||||
|
||||
// If end of an item then tell delegate
|
||||
if (!processed) {
|
||||
if (((feedType == FeedTypeRSS || feedType == FeedTypeRSS1) && [qName isEqualToString:@"item"]) ||
|
||||
(feedType == FeedTypeAtom && [qName isEqualToString:@"entry"])) {
|
||||
|
||||
// Dispatch item to delegate
|
||||
[self dispatchFeedItemToDelegate];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the document has finished parsing and send off info if needed (i.e. there were no items)
|
||||
if (!processed) {
|
||||
if ((feedType == FeedTypeRSS && [qName isEqualToString:@"rss"]) ||
|
||||
(feedType == FeedTypeRSS1 && [qName isEqualToString:@"rdf:RDF"]) ||
|
||||
(feedType == FeedTypeAtom && [qName isEqualToString:@"feed"])) {
|
||||
|
||||
// Document ending so if we havent sent off feed info yet, do so
|
||||
if (info && feedParseType != ParseTypeItemsOnly) [self dispatchFeedInfoToDelegate];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//- (void)parser:(NSXMLParser *)parser foundAttributeDeclarationWithName:(NSString *)attributeName
|
||||
// forElement:(NSString *)elementName type:(NSString *)type defaultValue:(NSString *)defaultValue {
|
||||
// MWXMLLog(@"NSXMLParser: foundAttributeDeclarationWithName: %@", attributeName);
|
||||
//}
|
||||
|
||||
- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock {
|
||||
MWXMLLog(@"NSXMLParser: foundCDATA (%d bytes)", CDATABlock.length);
|
||||
|
||||
// Remember characters
|
||||
NSString *string = nil;
|
||||
@try {
|
||||
|
||||
// Try decoding with NSUTF8StringEncoding & NSISOLatin1StringEncoding
|
||||
string = [[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
|
||||
if (!string) string = [[NSString alloc] initWithData:CDATABlock encoding:NSISOLatin1StringEncoding];
|
||||
|
||||
// Add - No need to encode as CDATA should not be encoded as it's ignored by the parser
|
||||
if (string) [currentText appendString:string];
|
||||
|
||||
} @catch (NSException * e) {
|
||||
} @finally {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
|
||||
MWXMLLog(@"NSXMLParser: foundCharacters: %@", string);
|
||||
|
||||
// Remember characters
|
||||
if (!parseStructureAsContent) {
|
||||
|
||||
// Add characters normally
|
||||
[currentText appendString:string];
|
||||
|
||||
} else {
|
||||
|
||||
// If parsing structure as content then we should encode characters
|
||||
[currentText appendString:[string stringByEncodingHTMLEntities]];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)parserDidStartDocument:(NSXMLParser *)parser {
|
||||
MWXMLLog(@"NSXMLParser: parserDidStartDocument");
|
||||
|
||||
// Debug Log
|
||||
MWLog(@"MWFeedParser: Parsing started");
|
||||
|
||||
// Inform delegate
|
||||
if ([delegate respondsToSelector:@selector(feedParserDidStart:)])
|
||||
[delegate feedParserDidStart:self];
|
||||
|
||||
}
|
||||
|
||||
- (void)parserDidEndDocument:(NSXMLParser *)parser {
|
||||
MWXMLLog(@"NSXMLParser: parserDidEndDocument");
|
||||
|
||||
// Debug Log
|
||||
MWLog(@"MWFeedParser: Parsing finished");
|
||||
|
||||
// Inform delegate
|
||||
[self parsingFinished];
|
||||
|
||||
}
|
||||
|
||||
// Call if parsing error occured or parse was aborted
|
||||
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
|
||||
MWXMLLog(@"NSXMLParser: parseErrorOccurred: %@", parseError);
|
||||
|
||||
// Fail with error
|
||||
if (!aborted) {
|
||||
// This method is called when legimitaly aboring the parser so ignore if this is the case
|
||||
[self parsingFailedWithErrorCode:MWErrorCodeFeedParsingError andDescription:[parseError localizedDescription]];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validError {
|
||||
MWXMLLog(@"NSXMLParser: validationErrorOccurred: %@", validError);
|
||||
|
||||
// Fail with error
|
||||
[self parsingFailedWithErrorCode:MWErrorCodeFeedValidationError andDescription:[validError localizedDescription]];
|
||||
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Send Items to Delegate
|
||||
|
||||
- (void)dispatchFeedInfoToDelegate {
|
||||
if (info) {
|
||||
|
||||
// Inform delegate
|
||||
if ([delegate respondsToSelector:@selector(feedParser:didParseFeedInfo:)])
|
||||
[delegate feedParser:self didParseFeedInfo:info];
|
||||
|
||||
// Debug log
|
||||
MWLog(@"MWFeedParser: Feed info for \"%@\" successfully parsed", info.title);
|
||||
|
||||
// Finish
|
||||
self.info = nil;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dispatchFeedItemToDelegate {
|
||||
if (item) {
|
||||
|
||||
// Process before hand
|
||||
if (!item.summary) { item.summary = item.content; item.content = nil; }
|
||||
if (!item.date && item.updated) { item.date = item.updated; }
|
||||
|
||||
// Debug log
|
||||
MWLog(@"MWFeedParser: Feed item \"%@\" successfully parsed", item.title);
|
||||
|
||||
// Inform delegate
|
||||
if ([delegate respondsToSelector:@selector(feedParser:didParseFeedItem:)])
|
||||
[delegate feedParser:self didParseFeedItem:item];
|
||||
|
||||
// Finish
|
||||
self.item = nil;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Helpers & Properties
|
||||
|
||||
// Set URL to parse and removing feed: uri scheme info
|
||||
// http://en.wikipedia.org/wiki/Feed:_URI_scheme
|
||||
- (void)setUrl:(NSURL *)value {
|
||||
|
||||
// Check if an string was passed as old init asked for NSString not NSURL
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
value = [NSURL URLWithString:(NSString *)value];
|
||||
}
|
||||
|
||||
// Create new instance of NSURL and check URL scheme
|
||||
NSURL *newURL = nil;
|
||||
if (value) {
|
||||
if ([value.scheme isEqualToString:@"feed"]) {
|
||||
|
||||
// Remove feed URL scheme
|
||||
newURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",
|
||||
([value.resourceSpecifier hasPrefix:@"//"] ? @"http:" : @""),
|
||||
value.resourceSpecifier]];
|
||||
|
||||
} else {
|
||||
|
||||
// Copy
|
||||
newURL = [value copy];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Set new url
|
||||
if (url) url = nil;
|
||||
url = newURL;
|
||||
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Misc
|
||||
|
||||
// Create an enclosure NSDictionary from enclosure (or link) attributes
|
||||
- (BOOL)createEnclosureFromAttributes:(NSDictionary *)attributes andAddToItem:(MWFeedItem *)currentItem {
|
||||
|
||||
// Create enclosure
|
||||
NSDictionary *enclosure = nil;
|
||||
NSString *encURL = nil, *encType = nil;
|
||||
NSNumber *encLength = nil;
|
||||
if (attributes) {
|
||||
switch (feedType) {
|
||||
case FeedTypeRSS: { // http://cyber.law.harvard.edu/rss/rss.html#ltenclosuregtSubelementOfLtitemgt
|
||||
// <enclosure>
|
||||
encURL = [attributes objectForKey:@"url"];
|
||||
encType = [attributes objectForKey:@"type"];
|
||||
encLength = [NSNumber numberWithLongLong:[((NSString *)[attributes objectForKey:@"length"]) longLongValue]];
|
||||
break;
|
||||
}
|
||||
case FeedTypeRSS1: { // http://www.xs4all.nl/~foz/mod_enclosure.html
|
||||
// <enc:enclosure>
|
||||
encURL = [attributes objectForKey:@"rdf:resource"];
|
||||
encType = [attributes objectForKey:@"enc:type"];
|
||||
encLength = [NSNumber numberWithLongLong:[((NSString *)[attributes objectForKey:@"enc:length"]) longLongValue]];
|
||||
break;
|
||||
}
|
||||
case FeedTypeAtom: { // http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rel_attribute
|
||||
// <link rel="enclosure" href=...
|
||||
if ([[attributes objectForKey:@"rel"] isEqualToString:@"enclosure"]) {
|
||||
encURL = [attributes objectForKey:@"href"];
|
||||
encType = [attributes objectForKey:@"type"];
|
||||
encLength = [NSNumber numberWithLongLong:[((NSString *)[attributes objectForKey:@"length"]) longLongValue]];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (encURL) {
|
||||
NSMutableDictionary *e = [[NSMutableDictionary alloc] initWithCapacity:3];
|
||||
[e setObject:encURL forKey:@"url"];
|
||||
if (encType) [e setObject:encType forKey:@"type"];
|
||||
if (encLength) [e setObject:encLength forKey:@"length"];
|
||||
enclosure = [NSDictionary dictionaryWithDictionary:e];
|
||||
}
|
||||
|
||||
// Add to item
|
||||
if (enclosure) {
|
||||
if (currentItem.enclosures) {
|
||||
currentItem.enclosures = [currentItem.enclosures arrayByAddingObject:enclosure];
|
||||
} else {
|
||||
currentItem.enclosures = [NSArray arrayWithObject:enclosure];
|
||||
}
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Process ATOM link and determine whether to ignore it, add it as the link element or add as enclosure
|
||||
// Links can be added to MWObject (info or item)
|
||||
- (BOOL)processAtomLink:(NSDictionary *)attributes andAddToMWObject:(id)MWObject {
|
||||
if (attributes && [attributes objectForKey:@"rel"]) {
|
||||
|
||||
// Use as link if rel == alternate
|
||||
if ([[attributes objectForKey:@"rel"] isEqualToString:@"alternate"]) {
|
||||
[MWObject setLink:[attributes objectForKey:@"href"]]; // Can be added to MWFeedItem or MWFeedInfo
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Use as enclosure if rel == enclosure
|
||||
if ([[attributes objectForKey:@"rel"] isEqualToString:@"enclosure"]) {
|
||||
if ([MWObject isMemberOfClass:[MWFeedItem class]]) { // Enclosures can only be added to MWFeedItem
|
||||
[self createEnclosureFromAttributes:attributes andAddToItem:(MWFeedItem *)MWObject];
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
68
MWFeedParser_Private.h
Normal file
68
MWFeedParser_Private.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// MWFeedParser_Private.h
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
@interface MWFeedParser ()
|
||||
|
||||
#pragma mark Private Properties
|
||||
|
||||
// Feed Downloading Properties
|
||||
@property (nonatomic, copy) NSURL *url;
|
||||
@property (nonatomic, retain) NSURLConnection *urlConnection;
|
||||
@property (nonatomic, retain) NSMutableData *asyncData;
|
||||
@property (nonatomic, retain) NSString *asyncTextEncodingName;
|
||||
|
||||
// Parsing Properties
|
||||
@property (nonatomic, retain) NSXMLParser *feedParser;
|
||||
@property (nonatomic, retain) NSString *currentPath;
|
||||
@property (nonatomic, retain) NSMutableString *currentText;
|
||||
@property (nonatomic, retain) NSDictionary *currentElementAttributes;
|
||||
@property (nonatomic, retain) MWFeedItem *item;
|
||||
@property (nonatomic, retain) MWFeedInfo *info;
|
||||
@property (nonatomic, copy) NSString *pathOfElementWithXHTMLType;
|
||||
|
||||
#pragma mark Private Methods
|
||||
|
||||
// Parsing Methods
|
||||
- (void)reset;
|
||||
- (void)abortParsingEarly;
|
||||
- (void)parsingFinished;
|
||||
- (void)parsingFailedWithErrorCode:(int)code andDescription:(NSString *)description;
|
||||
- (void)startParsingData:(NSData *)data textEncodingName:(NSString *)textEncodingName;
|
||||
|
||||
// Dispatching to Delegate
|
||||
- (void)dispatchFeedInfoToDelegate;
|
||||
- (void)dispatchFeedItemToDelegate;
|
||||
|
||||
// Error Handling
|
||||
|
||||
// Misc
|
||||
- (BOOL)createEnclosureFromAttributes:(NSDictionary *)attributes andAddToItem:(MWFeedItem *)currentItem;
|
||||
- (BOOL)processAtomLink:(NSDictionary *)attributes andAddToMWObject:(id)MWObject;
|
||||
|
||||
@end
|
||||
31
NSDate+InternetDateTime.h
Normal file
31
NSDate+InternetDateTime.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// NSDate+InternetDateTime.h
|
||||
// MWFeedParser
|
||||
//
|
||||
// Created by Michael Waterfall on 07/10/2010.
|
||||
// Copyright 2010 Michael Waterfall. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// Formatting hints
|
||||
typedef enum {
|
||||
DateFormatHintNone,
|
||||
DateFormatHintRFC822,
|
||||
DateFormatHintRFC3339
|
||||
} DateFormatHint;
|
||||
|
||||
// A category to parse internet date & time strings
|
||||
@interface NSDate (InternetDateTime)
|
||||
|
||||
// Get date from RFC3339 or RFC822 string
|
||||
// - A format/specification hint can be used to speed up,
|
||||
// otherwise both will be attempted in order to get a date
|
||||
+ (NSDate *)dateFromInternetDateTimeString:(NSString *)dateString
|
||||
formatHint:(DateFormatHint)hint;
|
||||
|
||||
// Get date from a string using a specific date specification
|
||||
+ (NSDate *)dateFromRFC3339String:(NSString *)dateString;
|
||||
+ (NSDate *)dateFromRFC822String:(NSString *)dateString;
|
||||
|
||||
@end
|
||||
136
NSDate+InternetDateTime.m
Normal file
136
NSDate+InternetDateTime.m
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
//
|
||||
// NSDate+InternetDateTime.m
|
||||
// MWFeedParser
|
||||
//
|
||||
// Created by Michael Waterfall on 07/10/2010.
|
||||
// Copyright 2010 Michael Waterfall. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSDate+InternetDateTime.h"
|
||||
|
||||
// Always keep the formatter around as they're expensive to instantiate
|
||||
static NSDateFormatter *_internetDateTimeFormatter = nil;
|
||||
|
||||
// Good info on internet dates here:
|
||||
// http://developer.apple.com/iphone/library/qa/qa2010/qa1480.html
|
||||
@implementation NSDate (InternetDateTime)
|
||||
|
||||
// Instantiate single date formatter
|
||||
+ (NSDateFormatter *)internetDateTimeFormatter {
|
||||
@synchronized(self) {
|
||||
if (!_internetDateTimeFormatter) {
|
||||
NSLocale *en_US_POSIX = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
|
||||
_internetDateTimeFormatter = [[NSDateFormatter alloc] init];
|
||||
[_internetDateTimeFormatter setLocale:en_US_POSIX];
|
||||
[_internetDateTimeFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
|
||||
}
|
||||
}
|
||||
return _internetDateTimeFormatter;
|
||||
}
|
||||
|
||||
// Get a date from a string - hint can be used to speed up
|
||||
+ (NSDate *)dateFromInternetDateTimeString:(NSString *)dateString formatHint:(DateFormatHint)hint {
|
||||
NSDate *date = nil;
|
||||
if (dateString) {
|
||||
if (hint != DateFormatHintRFC3339) {
|
||||
// Try RFC822 first
|
||||
date = [NSDate dateFromRFC822String:dateString];
|
||||
if (!date) date = [NSDate dateFromRFC3339String:dateString];
|
||||
} else {
|
||||
// Try RFC3339 first
|
||||
date = [NSDate dateFromRFC3339String:dateString];
|
||||
if (!date) date = [NSDate dateFromRFC822String:dateString];
|
||||
}
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
// See http://www.faqs.org/rfcs/rfc822.html
|
||||
+ (NSDate *)dateFromRFC822String:(NSString *)dateString {
|
||||
NSDate *date = nil;
|
||||
if (dateString) {
|
||||
NSDateFormatter *dateFormatter = [NSDate internetDateTimeFormatter];
|
||||
@synchronized(dateFormatter) {
|
||||
|
||||
// Process
|
||||
NSString *RFC822String = [[NSString stringWithString:dateString] uppercaseString];
|
||||
if ([RFC822String rangeOfString:@","].location != NSNotFound) {
|
||||
if (!date) { // Sun, 19 May 2002 15:21:36 GMT
|
||||
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzz"];
|
||||
date = [dateFormatter dateFromString:RFC822String];
|
||||
}
|
||||
if (!date) { // Sun, 19 May 2002 15:21 GMT
|
||||
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm zzz"];
|
||||
date = [dateFormatter dateFromString:RFC822String];
|
||||
}
|
||||
if (!date) { // Sun, 19 May 2002 15:21:36
|
||||
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss"];
|
||||
date = [dateFormatter dateFromString:RFC822String];
|
||||
}
|
||||
if (!date) { // Sun, 19 May 2002 15:21
|
||||
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm"];
|
||||
date = [dateFormatter dateFromString:RFC822String];
|
||||
}
|
||||
} else {
|
||||
if (!date) { // 19 May 2002 15:21:36 GMT
|
||||
[dateFormatter setDateFormat:@"d MMM yyyy HH:mm:ss zzz"];
|
||||
date = [dateFormatter dateFromString:RFC822String];
|
||||
}
|
||||
if (!date) { // 19 May 2002 15:21 GMT
|
||||
[dateFormatter setDateFormat:@"d MMM yyyy HH:mm zzz"];
|
||||
date = [dateFormatter dateFromString:RFC822String];
|
||||
}
|
||||
if (!date) { // 19 May 2002 15:21:36
|
||||
[dateFormatter setDateFormat:@"d MMM yyyy HH:mm:ss"];
|
||||
date = [dateFormatter dateFromString:RFC822String];
|
||||
}
|
||||
if (!date) { // 19 May 2002 15:21
|
||||
[dateFormatter setDateFormat:@"d MMM yyyy HH:mm"];
|
||||
date = [dateFormatter dateFromString:RFC822String];
|
||||
}
|
||||
}
|
||||
if (!date) NSLog(@"Could not parse RFC822 date: \"%@\" Possible invalid format.", dateString);
|
||||
|
||||
}
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
// See http://www.faqs.org/rfcs/rfc3339.html
|
||||
+ (NSDate *)dateFromRFC3339String:(NSString *)dateString {
|
||||
NSDate *date = nil;
|
||||
if (dateString) {
|
||||
NSDateFormatter *dateFormatter = [NSDate internetDateTimeFormatter];
|
||||
@synchronized(dateFormatter) {
|
||||
|
||||
// Process date
|
||||
NSString *RFC3339String = [[NSString stringWithString:dateString] uppercaseString];
|
||||
RFC3339String = [RFC3339String stringByReplacingOccurrencesOfString:@"Z" withString:@"-0000"];
|
||||
// Remove colon in timezone as it breaks NSDateFormatter in iOS 4+.
|
||||
// - see https://devforums.apple.com/thread/45837
|
||||
if (RFC3339String.length > 20) {
|
||||
RFC3339String = [RFC3339String stringByReplacingOccurrencesOfString:@":"
|
||||
withString:@""
|
||||
options:0
|
||||
range:NSMakeRange(20, RFC3339String.length-20)];
|
||||
}
|
||||
if (!date) { // 1996-12-19T16:39:57-0800
|
||||
[dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ"];
|
||||
date = [dateFormatter dateFromString:RFC3339String];
|
||||
}
|
||||
if (!date) { // 1937-01-01T12:00:27.87+0020
|
||||
[dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSZZZ"];
|
||||
date = [dateFormatter dateFromString:RFC3339String];
|
||||
}
|
||||
if (!date) { // 1937-01-01T12:00:27
|
||||
[dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss"];
|
||||
date = [dateFormatter dateFromString:RFC3339String];
|
||||
}
|
||||
if (!date) NSLog(@"Could not parse RFC3339 date: \"%@\" Possible invalid format.", dateString);
|
||||
|
||||
}
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
@end
|
||||
67
NSString+HTML.h
Normal file
67
NSString+HTML.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
//
|
||||
// NSString+HTML.h
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// Dependant upon GTMNSString+HTML
|
||||
|
||||
@interface NSString (HTML)
|
||||
|
||||
// Strips HTML tags & comments, removes extra whitespace and decodes HTML character entities.
|
||||
- (NSString *)stringByConvertingHTMLToPlainText;
|
||||
|
||||
// Decode all HTML entities using GTM.
|
||||
- (NSString *)stringByDecodingHTMLEntities;
|
||||
|
||||
// Encode all HTML entities using GTM.
|
||||
- (NSString *)stringByEncodingHTMLEntities;
|
||||
|
||||
// Minimal unicode encoding will only cover characters from table
|
||||
// A.2.2 of http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters
|
||||
// which is what you want for a unicode encoded webpage.
|
||||
- (NSString *)stringByEncodingHTMLEntities:(BOOL)isUnicode;
|
||||
|
||||
// Replace newlines with <br /> tags.
|
||||
- (NSString *)stringWithNewLinesAsBRs;
|
||||
|
||||
// Remove newlines and white space from string.
|
||||
- (NSString *)stringByRemovingNewLinesAndWhitespace;
|
||||
|
||||
// Wrap plain URLs in <a href="..." class="linkified">...</a>
|
||||
// - Ignores URLs inside tags (any URL beginning with =")
|
||||
// - HTTP & HTTPS schemes only
|
||||
// - Only works in iOS 4+ as we use NSRegularExpression (returns self if not supported so be careful with NSMutableStrings)
|
||||
// - Expression: (?<!=")\b((http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)
|
||||
// - Adapted from http://regexlib.com/REDetails.aspx?regexp_id=96
|
||||
- (NSString *)stringByLinkifyingURLs;
|
||||
|
||||
// DEPRECIATED - Please use NSString stringByConvertingHTMLToPlainText
|
||||
- (NSString *)stringByStrippingTags __attribute__((deprecated));
|
||||
|
||||
@end
|
||||
318
NSString+HTML.m
Normal file
318
NSString+HTML.m
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
//
|
||||
// NSString+HTML.m
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "NSString+HTML.h"
|
||||
#import "GTMNSString+HTML.h"
|
||||
|
||||
@implementation NSString (HTML)
|
||||
|
||||
#pragma mark - Instance Methods
|
||||
|
||||
- (NSString *)stringByConvertingHTMLToPlainText {
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
// Character sets
|
||||
NSCharacterSet *stopCharacters = [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@"< \t\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
|
||||
NSCharacterSet *newLineAndWhitespaceCharacters = [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@" \t\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
|
||||
NSCharacterSet *tagNameCharacters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
|
||||
|
||||
// Scan and find all tags
|
||||
NSMutableString *result = [[NSMutableString alloc] initWithCapacity:self.length];
|
||||
NSScanner *scanner = [[NSScanner alloc] initWithString:self];
|
||||
[scanner setCharactersToBeSkipped:nil];
|
||||
[scanner setCaseSensitive:YES];
|
||||
NSString *str = nil, *tagName = nil;
|
||||
BOOL dontReplaceTagWithSpace = NO;
|
||||
do {
|
||||
|
||||
// Scan up to the start of a tag or whitespace
|
||||
if ([scanner scanUpToCharactersFromSet:stopCharacters intoString:&str]) {
|
||||
[result appendString:str];
|
||||
str = nil; // reset
|
||||
}
|
||||
|
||||
// Check if we've stopped at a tag/comment or whitespace
|
||||
if ([scanner scanString:@"<" intoString:NULL]) {
|
||||
|
||||
// Stopped at a comment or tag
|
||||
if ([scanner scanString:@"!--" intoString:NULL]) {
|
||||
|
||||
// Comment
|
||||
[scanner scanUpToString:@"-->" intoString:NULL];
|
||||
[scanner scanString:@"-->" intoString:NULL];
|
||||
|
||||
} else {
|
||||
|
||||
// Tag - remove and replace with space unless it's
|
||||
// a closing inline tag then dont replace with a space
|
||||
if ([scanner scanString:@"/" intoString:NULL]) {
|
||||
|
||||
// Closing tag - replace with space unless it's inline
|
||||
tagName = nil; dontReplaceTagWithSpace = NO;
|
||||
if ([scanner scanCharactersFromSet:tagNameCharacters intoString:&tagName]) {
|
||||
tagName = [tagName lowercaseString];
|
||||
dontReplaceTagWithSpace = ([tagName isEqualToString:@"a"] ||
|
||||
[tagName isEqualToString:@"b"] ||
|
||||
[tagName isEqualToString:@"i"] ||
|
||||
[tagName isEqualToString:@"q"] ||
|
||||
[tagName isEqualToString:@"span"] ||
|
||||
[tagName isEqualToString:@"em"] ||
|
||||
[tagName isEqualToString:@"strong"] ||
|
||||
[tagName isEqualToString:@"cite"] ||
|
||||
[tagName isEqualToString:@"abbr"] ||
|
||||
[tagName isEqualToString:@"acronym"] ||
|
||||
[tagName isEqualToString:@"label"]);
|
||||
}
|
||||
|
||||
// Replace tag with string unless it was an inline
|
||||
if (!dontReplaceTagWithSpace && result.length > 0 && ![scanner isAtEnd]) [result appendString:@" "];
|
||||
|
||||
}
|
||||
|
||||
// Scan past tag
|
||||
[scanner scanUpToString:@">" intoString:NULL];
|
||||
[scanner scanString:@">" intoString:NULL];
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Stopped at whitespace - replace all whitespace and newlines with a space
|
||||
if ([scanner scanCharactersFromSet:newLineAndWhitespaceCharacters intoString:NULL]) {
|
||||
if (result.length > 0 && ![scanner isAtEnd]) [result appendString:@" "]; // Dont append space to beginning or end of result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} while (![scanner isAtEnd]);
|
||||
|
||||
|
||||
// Decode HTML entities and return
|
||||
NSString *retString = [result stringByDecodingHTMLEntities] ;
|
||||
|
||||
|
||||
|
||||
// Return
|
||||
return retString;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)stringByDecodingHTMLEntities {
|
||||
// Can return self so create new string if we're a mutable string
|
||||
return [NSString stringWithString:[self gtm_stringByUnescapingFromHTML]];
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)stringByEncodingHTMLEntities {
|
||||
// Can return self so create new string if we're a mutable string
|
||||
return [NSString stringWithString:[self gtm_stringByEscapingForAsciiHTML]];
|
||||
}
|
||||
|
||||
- (NSString *)stringByEncodingHTMLEntities:(BOOL)isUnicode {
|
||||
// Can return self so create new string if we're a mutable string
|
||||
return [NSString stringWithString:(isUnicode ? [self gtm_stringByEscapingForHTML] : [self gtm_stringByEscapingForAsciiHTML])];
|
||||
}
|
||||
|
||||
- (NSString *)stringWithNewLinesAsBRs {
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
// Strange New lines:
|
||||
// Next Line, U+0085
|
||||
// Form Feed, U+000C
|
||||
// Line Separator, U+2028
|
||||
// Paragraph Separator, U+2029
|
||||
|
||||
// Scanner
|
||||
NSScanner *scanner = [[NSScanner alloc] initWithString:self];
|
||||
[scanner setCharactersToBeSkipped:nil];
|
||||
NSMutableString *result = [[NSMutableString alloc] init];
|
||||
NSString *temp;
|
||||
NSCharacterSet *newLineCharacters = [NSCharacterSet characterSetWithCharactersInString:
|
||||
[NSString stringWithFormat:@"\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
|
||||
// Scan
|
||||
do {
|
||||
|
||||
// Get non new line characters
|
||||
temp = nil;
|
||||
[scanner scanUpToCharactersFromSet:newLineCharacters intoString:&temp];
|
||||
if (temp) [result appendString:temp];
|
||||
temp = nil;
|
||||
|
||||
// Add <br /> s
|
||||
if ([scanner scanString:@"\r\n" intoString:nil]) {
|
||||
|
||||
// Combine \r\n into just 1 <br />
|
||||
[result appendString:@"<br />"];
|
||||
|
||||
} else if ([scanner scanCharactersFromSet:newLineCharacters intoString:&temp]) {
|
||||
|
||||
// Scan other new line characters and add <br /> s
|
||||
if (temp) {
|
||||
for (int i = 0; i < temp.length; i++) {
|
||||
[result appendString:@"<br />"];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} while (![scanner isAtEnd]);
|
||||
|
||||
NSString *retString = [NSString stringWithString:result] ;
|
||||
|
||||
|
||||
// Return
|
||||
return retString ;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)stringByRemovingNewLinesAndWhitespace {
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
// Strange New lines:
|
||||
// Next Line, U+0085
|
||||
// Form Feed, U+000C
|
||||
// Line Separator, U+2028
|
||||
// Paragraph Separator, U+2029
|
||||
|
||||
// Scanner
|
||||
NSScanner *scanner = [[NSScanner alloc] initWithString:self];
|
||||
[scanner setCharactersToBeSkipped:nil];
|
||||
NSMutableString *result = [[NSMutableString alloc] init];
|
||||
NSString *temp;
|
||||
NSCharacterSet *newLineAndWhitespaceCharacters = [NSCharacterSet characterSetWithCharactersInString:
|
||||
[NSString stringWithFormat:@" \t\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
|
||||
// Scan
|
||||
while (![scanner isAtEnd]) {
|
||||
|
||||
// Get non new line or whitespace characters
|
||||
temp = nil;
|
||||
[scanner scanUpToCharactersFromSet:newLineAndWhitespaceCharacters intoString:&temp];
|
||||
if (temp) [result appendString:temp];
|
||||
|
||||
// Replace with a space
|
||||
if ([scanner scanCharactersFromSet:newLineAndWhitespaceCharacters intoString:NULL]) {
|
||||
if (result.length > 0 && ![scanner isAtEnd]) // Dont append space to beginning or end of result
|
||||
[result appendString:@" "];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
NSString *retString = [NSString stringWithString:result] ;
|
||||
|
||||
|
||||
// Return
|
||||
return retString ;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)stringByLinkifyingURLs {
|
||||
if (!NSClassFromString(@"NSRegularExpression")) return self;
|
||||
@autoreleasepool {
|
||||
|
||||
NSString *pattern = @"(?<!=\")\\b((http|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%%&:/~\\+#]*[\\w\\-\\@?^=%%&/~\\+#])?)";
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil];
|
||||
NSString *modifiedString = [regex stringByReplacingMatchesInString:self options:0 range:NSMakeRange(0, [self length])
|
||||
withTemplate:@"<a href=\"$1\" class=\"linkified\">$1</a>"];
|
||||
|
||||
return modifiedString ;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)stringByStrippingTags {
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
// Find first & and short-cut if we can
|
||||
NSUInteger ampIndex = [self rangeOfString:@"<" options:NSLiteralSearch].location;
|
||||
if (ampIndex == NSNotFound) {
|
||||
return [NSString stringWithString:self]; // return copy of string as no tags found
|
||||
}
|
||||
|
||||
// Scan and find all tags
|
||||
NSScanner *scanner = [NSScanner scannerWithString:self];
|
||||
[scanner setCharactersToBeSkipped:nil];
|
||||
NSMutableSet *tags = [[NSMutableSet alloc] init];
|
||||
NSString *tag;
|
||||
do {
|
||||
|
||||
// Scan up to <
|
||||
tag = nil;
|
||||
[scanner scanUpToString:@"<" intoString:NULL];
|
||||
[scanner scanUpToString:@">" intoString:&tag];
|
||||
|
||||
// Add to set
|
||||
if (tag) {
|
||||
NSString *t = [[NSString alloc] initWithFormat:@"%@>", tag];
|
||||
[tags addObject:t];
|
||||
}
|
||||
|
||||
} while (![scanner isAtEnd]);
|
||||
|
||||
// Strings
|
||||
NSMutableString *result = [[NSMutableString alloc] initWithString:self];
|
||||
NSString *finalString;
|
||||
|
||||
// Replace tags
|
||||
NSString *replacement;
|
||||
for (NSString *t in tags) {
|
||||
|
||||
// Replace tag with space unless it's an inline element
|
||||
replacement = @" ";
|
||||
if ([t isEqualToString:@"<a>"] ||
|
||||
[t isEqualToString:@"</a>"] ||
|
||||
[t isEqualToString:@"<span>"] ||
|
||||
[t isEqualToString:@"</span>"] ||
|
||||
[t isEqualToString:@"<strong>"] ||
|
||||
[t isEqualToString:@"</strong>"] ||
|
||||
[t isEqualToString:@"<em>"] ||
|
||||
[t isEqualToString:@"</em>"]) {
|
||||
replacement = @"";
|
||||
}
|
||||
|
||||
// Replace
|
||||
[result replaceOccurrencesOfString:t
|
||||
withString:replacement
|
||||
options:NSLiteralSearch
|
||||
range:NSMakeRange(0, result.length)];
|
||||
}
|
||||
|
||||
// Remove multi-spaces and line breaks
|
||||
finalString = [result stringByRemovingNewLinesAndWhitespace];
|
||||
|
||||
|
||||
// Return
|
||||
return finalString ;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
44
NSString+XMLEntities.h
Normal file
44
NSString+XMLEntities.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// NSString+XMLEntities.h
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// Import new HTML category
|
||||
#import "NSString+HTML.h"
|
||||
|
||||
// THIS CLASS IS DEPRECIATED 03/08/2010
|
||||
// REPLACED BY NSString+HTML
|
||||
|
||||
@interface NSString (XMLEntities)
|
||||
|
||||
// Old Instance Methods
|
||||
- (NSString *)stringByDecodingXMLEntities;
|
||||
- (NSString *)stringByEncodingXMLEntities;
|
||||
|
||||
@end
|
||||
45
NSString+XMLEntities.m
Normal file
45
NSString+XMLEntities.m
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// NSString+XMLEntities.m
|
||||
// MWFeedParser
|
||||
//
|
||||
// Copyright (c) 2010 Michael Waterfall
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 1. The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// 2. This Software cannot be used to archive or collect data such as (but not
|
||||
// limited to) that of events, news, experiences and activities, for the
|
||||
// purpose of any concept relating to diary/journal keeping.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import "NSString+XMLEntities.h"
|
||||
|
||||
// THIS CLASS IS DEPRECIATED 03/08/2010
|
||||
// REPLACED BY NSString+HTML
|
||||
|
||||
@implementation NSString (XMLEntities)
|
||||
|
||||
- (NSString *)stringByDecodingXMLEntities {
|
||||
return [self stringByDecodingHTMLEntities];
|
||||
}
|
||||
|
||||
- (NSString *)stringByEncodingXMLEntities {
|
||||
return [self stringByEncodingHTMLEntities];
|
||||
}
|
||||
|
||||
@end
|
||||
Loading…
Reference in a new issue