Skip to content
Browse files

added URL-Unshortener

  • Loading branch information...
1 parent 8502c3c commit 1ecfdab28c065b6d5be26415f00887c6b50b11a1 @odrobnik odrobnik committed Jun 2, 2012
Showing with 112 additions and 0 deletions.
  1. +33 −0 Core/Source/NSURL+DTUnshorten.h
  2. +67 −0 Core/Source/NSURL+DTUnshorten.m
  3. +12 −0 DTFoundation.xcodeproj/project.pbxproj
View
33 Core/Source/NSURL+DTUnshorten.h
@@ -0,0 +1,33 @@
+//
+// NSURL+DTUnshorten.h
+// DTFoundation
+//
+// Created by Oliver Drobnik on 6/2/12.
+// Copyright (c) 2012 Cocoanetics. All rights reserved.
+//
+
+/** Method for getting the full length URL for a shortened one.
+
+For example:
+
+ NSURL *url = [NSURL URLWithString:@"buff.ly/L4uGoza"];
+
+ [url unshortenWithCompletion:^(NSURL *url) {
+ NSLog(@"Unshortened: %@", url);
+ }];
+
+ */
+
+typedef void (^NSURLUnshortenCompletionHandler)(NSURL *);
+
+@interface NSURL (DTUnshorten)
+
+/**
+ Unshortens the receiver and returns the long URL via the completion handler.
+
+ Results are cached and therefore a subsequent call for the same receiver will return instantly if the result is still present in the cache.
+ @param completion The completion handler
+ */
+- (void)unshortenWithCompletion:(NSURLUnshortenCompletionHandler)completion;
+
+@end
View
67 Core/Source/NSURL+DTUnshorten.m
@@ -0,0 +1,67 @@
+//
+// NSURL+DTUnshorten.m
+// DTFoundation
+//
+// Created by Oliver Drobnik on 6/2/12.
+// Copyright (c) 2012 Cocoanetics. All rights reserved.
+//
+
+#import "NSURL+DTUnshorten.h"
+
+// force this category to be loaded by linker
+MAKE_CATEGORIES_LOADABLE(NSURL_DTUnshorten);
+
+@implementation NSURL (DTUnshorten)
+
+- (void)unshortenWithCompletion:(NSURLUnshortenCompletionHandler)completion
+{
+ static NSCache *unshortenCache = nil;
+ static dispatch_queue_t shortenQueue = NULL;
+
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ unshortenCache = [[NSCache alloc] init];
+ shortenQueue = dispatch_queue_create("DTUnshortenQueue", 0);
+ });
+
+ NSURL *shortURL = self;
+
+ // assume HTTP if scheme is missing
+ if (![self scheme])
+ {
+ NSString *str = [@"http://" stringByAppendingString:[self absoluteString]];
+ shortURL = [NSURL URLWithString:str];
+ }
+
+ dispatch_async(shortenQueue, ^{
+ // look into cache first
+ NSURL *longURL = [unshortenCache objectForKey:shortURL];
+
+ // nothing cached, load it
+ if (!longURL)
+ {
+ NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:shortURL];
+ request.HTTPMethod = @"HEAD";
+
+ NSError *error = nil;
+ NSHTTPURLResponse *response = nil;
+
+ [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
+
+ longURL = [response URL];
+
+ // cache result
+ if (longURL)
+ {
+ [unshortenCache setObject:longURL forKey:shortURL];
+ }
+ }
+
+ if (completion)
+ {
+ completion(longURL);
+ }
+ });
+}
+
+@end
View
12 DTFoundation.xcodeproj/project.pbxproj
@@ -91,6 +91,10 @@
A77DD42514E825FC00F34B03 /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = A77DD41414E825FC00F34B03 /* zip.c */; };
A77DD42614E825FC00F34B03 /* zip.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD41514E825FC00F34B03 /* zip.h */; };
A77DD42714E825FC00F34B03 /* zip.h in Headers */ = {isa = PBXBuildFile; fileRef = A77DD41514E825FC00F34B03 /* zip.h */; };
+ A79231CE157A0B9400C3ACBB /* NSURL+DTUnshorten.h in Headers */ = {isa = PBXBuildFile; fileRef = A79231CC157A0B9400C3ACBB /* NSURL+DTUnshorten.h */; };
+ A79231CF157A0B9400C3ACBB /* NSURL+DTUnshorten.h in Headers */ = {isa = PBXBuildFile; fileRef = A79231CC157A0B9400C3ACBB /* NSURL+DTUnshorten.h */; };
+ A79231D0157A0B9400C3ACBB /* NSURL+DTUnshorten.m in Sources */ = {isa = PBXBuildFile; fileRef = A79231CD157A0B9400C3ACBB /* NSURL+DTUnshorten.m */; };
+ A79231D1157A0B9400C3ACBB /* NSURL+DTUnshorten.m in Sources */ = {isa = PBXBuildFile; fileRef = A79231CD157A0B9400C3ACBB /* NSURL+DTUnshorten.m */; };
A7949A3A14C963F500A8CCDE /* DTHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7949A3814C963F500A8CCDE /* DTHTMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
A7949A3B14C963F500A8CCDE /* DTHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = A7949A3814C963F500A8CCDE /* DTHTMLParser.h */; settings = {ATTRIBUTES = (Public, ); }; };
A7949A3C14C963F500A8CCDE /* DTHTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = A7949A3914C963F500A8CCDE /* DTHTMLParser.m */; };
@@ -190,6 +194,8 @@
A77DD41314E825FC00F34B03 /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = "<group>"; };
A77DD41414E825FC00F34B03 /* zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zip.c; sourceTree = "<group>"; };
A77DD41514E825FC00F34B03 /* zip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = "<group>"; };
+ A79231CC157A0B9400C3ACBB /* NSURL+DTUnshorten.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+DTUnshorten.h"; sourceTree = "<group>"; };
+ A79231CD157A0B9400C3ACBB /* NSURL+DTUnshorten.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+DTUnshorten.m"; sourceTree = "<group>"; };
A7949A3814C963F500A8CCDE /* DTHTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTHTMLParser.h; sourceTree = "<group>"; };
A7949A3914C963F500A8CCDE /* DTHTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTHTMLParser.m; sourceTree = "<group>"; };
A7AB8BF8156AA00700CBAB7E /* UIApplication+DTNetworkActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIApplication+DTNetworkActivity.h"; sourceTree = "<group>"; };
@@ -348,6 +354,8 @@
A70B4CCD1486621B00873A4A /* NSURL+DTAppLinks.m */,
A70B4CCE1486621B00873A4A /* NSURL+DTPrefLinks.h */,
A70B4CCF1486621B00873A4A /* NSURL+DTPrefLinks.m */,
+ A79231CC157A0B9400C3ACBB /* NSURL+DTUnshorten.h */,
+ A79231CD157A0B9400C3ACBB /* NSURL+DTUnshorten.m */,
A7200AC9150917FD00D81719 /* UIImage+DTFoundation.h */,
A7200ACA150917FD00D81719 /* UIImage+DTFoundation.m */,
A72C110314A4946800F4EF69 /* UIView+DTFoundation.h */,
@@ -451,6 +459,7 @@
FA4264F7155D6B5B00E39D79 /* DTSmartPagingScrollView.h in Headers */,
A7D8C2AB15643C4E009E94AD /* DTPieProgressIndicator.h in Headers */,
A7AB8BFB156AA00700CBAB7E /* UIApplication+DTNetworkActivity.h in Headers */,
+ A79231CF157A0B9400C3ACBB /* NSURL+DTUnshorten.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -491,6 +500,7 @@
FA4264F6155D6B5B00E39D79 /* DTSmartPagingScrollView.h in Headers */,
A7D8C2AA15643C4E009E94AD /* DTPieProgressIndicator.h in Headers */,
A7AB8BFA156AA00700CBAB7E /* UIApplication+DTNetworkActivity.h in Headers */,
+ A79231CE157A0B9400C3ACBB /* NSURL+DTUnshorten.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -650,6 +660,7 @@
FA4264F9155D6B5B00E39D79 /* DTSmartPagingScrollView.m in Sources */,
A7D8C2AD15643C4E009E94AD /* DTPieProgressIndicator.m in Sources */,
A7AB8BFD156AA00700CBAB7E /* UIApplication+DTNetworkActivity.m in Sources */,
+ A79231D1157A0B9400C3ACBB /* NSURL+DTUnshorten.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -686,6 +697,7 @@
FA4264F8155D6B5B00E39D79 /* DTSmartPagingScrollView.m in Sources */,
A7D8C2AC15643C4E009E94AD /* DTPieProgressIndicator.m in Sources */,
A7AB8BFC156AA00700CBAB7E /* UIApplication+DTNetworkActivity.m in Sources */,
+ A79231D0157A0B9400C3ACBB /* NSURL+DTUnshorten.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

0 comments on commit 1ecfdab

Please sign in to comment.
Something went wrong with that request. Please try again.