Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# OS X
.DS_Store

# Xcode
build/
*.pbxuser

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you got the most important files in your gitignore - GitHub has an Obj-C gitignore with a few more lines here: https://github.com/github/gitignore/blob/master/Objective-C.gitignore

!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa
**/*.xcworkspace

# CocoaPods
Pods
482 changes: 482 additions & 0 deletions YATC.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions YATC/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="Ieg-Yx-aho">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
</dependencies>
<scenes>
<!--View Controller - YATC-->
<scene sceneID="MCp-oN-Yu0">
<objects>
<tableViewController id="lUo-y5-Qci" customClass="TWCViewController" sceneMemberID="viewController">
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" allowsSelection="NO" rowHeight="90" sectionHeaderHeight="22" sectionFooterHeight="22" id="Rg5-ga-NaX">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="cell" textLabel="TKz-TM-R1J" detailTextLabel="0Cv-ej-Qic" rowHeight="90" style="IBUITableViewCellStyleSubtitle" id="fCY-3e-dpo">
<rect key="frame" x="0.0" y="86" width="320" height="90"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="fCY-3e-dpo" id="TF2-zu-J5K">
<rect key="frame" x="0.0" y="0.0" width="320" height="89"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="mijustin" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="TKz-TM-R1J">
<rect key="frame" x="15" y="20" width="44" height="15"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="12"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" text="Just had my 3rd article published on The Next Web: http://t.co/W6Ld4vCnJh" lineBreakMode="tailTruncation" numberOfLines="4" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="267" id="0Cv-ej-Qic">
<rect key="frame" x="15" y="35" width="267" height="34"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
</tableView>
<navigationItem key="navigationItem" title="YATC" id="nkI-LR-be3"/>
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="dV9-nf-p6P">
<autoresizingMask key="autoresizingMask"/>
</refreshControl>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="vaf-dh-goj" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="432" y="40"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="nSk-ZG-tcg">
<objects>
<navigationController definesPresentationContext="YES" id="Ieg-Yx-aho" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="kPj-03-Mct">
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="lUo-y5-Qci" kind="relationship" relationship="rootViewController" id="Tnd-g3-diH"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="I2O-2p-0si" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-102" y="40"/>
</scene>
</scenes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>
23 changes: 23 additions & 0 deletions YATC/Images.xcassets/AppIcon.appiconset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
23 changes: 23 additions & 0 deletions YATC/Images.xcassets/LaunchImage.launchimage/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"orientation" : "portrait",
"idiom" : "iphone",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"subtype" : "retina4",
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
15 changes: 15 additions & 0 deletions YATC/TWCAppDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// TWCAppDelegate.h
// YATC
//
// Created by Jacob Krall on 2/9/14.
// Copyright (c) 2014 Jacob Krall. All rights reserved.
//

@import UIKit;

@interface TWCAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end
46 changes: 46 additions & 0 deletions YATC/TWCAppDelegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// TWCAppDelegate.m
// YATC
//
// Created by Jacob Krall on 2/9/14.
// Copyright (c) 2014 Jacob Krall. All rights reserved.
//

#import "TWCAppDelegate.h"

@implementation TWCAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
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
13 changes: 13 additions & 0 deletions YATC/TWCViewController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// TWCViewController.h
// YATC
//
// Created by Jacob Krall on 2/9/14.
// Copyright (c) 2014 Jacob Krall. All rights reserved.
//

@import UIKit;

@interface TWCViewController : UITableViewController

@end
156 changes: 156 additions & 0 deletions YATC/TWCViewController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
//
// TWCViewController.m
// YATC
//
// Created by Jacob Krall on 2/9/14.
// Copyright (c) 2014 Jacob Krall. All rights reserved.
//

@import Accounts;
@import Social;
#import "TWCViewController.h"

@interface TWCViewController ()

@property NSArray *entries;

// Twitter connection code shamelessly stolen from
// https://dev.twitter.com/docs/ios/making-api-requests-slrequest
@property (nonatomic) ACAccountStore *accountStore;

@end

@implementation TWCViewController

- (BOOL)userHasAccessToTwitter
{
return [SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter];
}

- (void)viewDidLoad
{
[super viewDidLoad];

[self fetchTimelineForUser];
[self setupRefreshControl];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
if(self = [super initWithCoder:aDecoder])
{
self.entries = @[];
self.accountStore = [ACAccountStore new];
}

return self;
}

- (void) setupRefreshControl
{
// HACK: If I just use `self.refreshControl` here, a wacky blank cell
// remains at the top of the TableView after refresh.
// Using a brand-new UIRefreshControl eliminates this bug.
UIRefreshControl *refreshControl = [UIRefreshControl new];
[refreshControl addTarget:self action:@selector(fetchTimelineForUser)
forControlEvents:UIControlEventValueChanged];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Updating data…"];

self.refreshControl = refreshControl;
}

- (void)fetchTimelineForUser
{
// Step 0: Check that the user has local Twitter accounts
if ([self userHasAccessToTwitter]) {
// Step 1: Obtain access to the user's Twitter accounts
ACAccountType *twitterAccountType =
[self.accountStore accountTypeWithAccountTypeIdentifier:
ACAccountTypeIdentifierTwitter];

[self.accountStore
requestAccessToAccountsWithType:twitterAccountType
options:nil
completion:^(BOOL granted, NSError *error) {
if (granted) {
// Step 2: Create a request
NSArray *twitterAccounts =
[self.accountStore accountsWithAccountType:twitterAccountType];
NSURL *url = [NSURL URLWithString:@"https://api.twitter.com"
@"/1.1/statuses/home_timeline.json"];
NSDictionary *params = @{@"count" : @"100", @"include_entities": @"false"};
SLRequest *request =
[SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodGET
URL:url
parameters:params];
// Attach an account to the request
[request setAccount:[twitterAccounts lastObject]];

// Step 3: Execute the request
[request performRequestWithHandler:
^(NSData *responseData,
NSHTTPURLResponse *urlResponse,
NSError *error) {
if (responseData) {
if (urlResponse.statusCode >= 200 &&
urlResponse.statusCode < 300) {
NSError *jsonError;
NSArray *timelineData =
[NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingAllowFragments error:&jsonError];
if (timelineData) {
self.entries = timelineData;
NSLog(@"got %ld", (long)(timelineData.count));
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
[self.refreshControl endRefreshing];
});
}
else {
// Our JSON deserialization went awry
NSLog(@"JSON Error: %@", [jsonError localizedDescription]);
}
}
else {
// The server did not respond ... were we rate-limited?
NSLog(@"The response status code is %ld",
(long)(urlResponse.statusCode));
}
}
}];
}
else {
// Access was not granted, or an error occurred
NSLog(@"%@", [error localizedDescription]);
}
}];
} else {
NSLog(@"!userHasAccessToTwitter");
}
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.entries.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:@"cell"
forIndexPath:indexPath];
NSDictionary* tweet = self.entries[indexPath.row];

cell.textLabel.text = tweet[@"user"][@"screen_name"];
cell.detailTextLabel.text = tweet[@"text"];
return cell;
}

@end
Loading