#100DaysOfCode - Antique
Listed below are my entries to #100DaysOfCode
Day 1: Distance between two CLLocation objects.
The code below is written in Swift and as of Xcode 11.5 and iOS 13.5.x is still correct.
func distance(me: CLLocation, other: CLLocation) -> Double {
return me.distance(from: other) / 1000 // km
}
func distance(from location: CLLocation) -> CLLocationDistance
returns the value in metres and can be divided by 1000 to return kilometres or 1609.34 to return miles.
Day 2: Generating a random password
The code below is written in Python and as of Python 3.8.x is still correct.
def generatePassword():
lowercase = "abcdefghijklmnopqrstuvwxyz"
uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
numbers = "1234567890"
special = "!@#$%^&*()[]{}-_=+|;:'""',.<>/?"
password_length = input("Enter desired password length:\n")
length = int(password_length)
allow_special = input("Allow special characters? (Y/N)\n")
allow_special_chars = str(allow_special)
password = ""
for char in range(length):
if allow_special_chars.upper() == "N":
password += random.choice(lowercase + uppercase + numbers)
else:
password += random.choice(lowercase + uppercase + numbers + special)
print(password)
# usage: generatePassword()
Day 3: Tweet a Reddit post with a specific flair
The code below is written in Python and as of Python 3.8.x is still correct.
import tweepy
import praw
import re
from tinydb import TinyDB, where
pattern = "FLAIR_NAME"
def getDatabase():
print('Loading Database...')
database = TinyDB("/path/to/database.json")
print('Loaded Database...')
return database
def saveSubmission(submission):
print('Saving Submission ID...')
database = getDatabase()
database.insert({
'submission_id': submission
})
print('Saved Submission ID...')
def loginReddit():
print('Logging in... (Reddit)')
reddit = praw.Reddit(client_id='', client_secret='', user_agent='')
print('Logged in... (Reddit)')
return reddit
def loginTwitter():
print('Logging in... (Twitter)')
twitter_auth_keys = {
"consumer_key" : "",
"consumer_secret" : "",
"access_token" : "",
"access_token_secret" : ""
}
auth = tweepy.OAuthHandler(twitter_auth_keys['consumer_key'], twitter_auth_keys['consumer_secret'])
auth.set_access_token(twitter_auth_keys['access_token'], twitter_auth_keys['access_token_secret'])
api = tweepy.API(auth)
print('Logged in... (Twitter)')
return api
def postTweet(submission):
print('Posting Tweet...')
twitter = loginTwitter()
twitter.update_status('New Release - ' + submission.title + '\n' + submission.url)
def connectSubreddit():
subreddit = loginReddit().subreddit('SUBREDDIT_NAME')
return subreddit
def getSubmissions():
subreddit = connectSubreddit()
print('Connected to /r/' + str(subreddit))
print('Getting submissions...')
for submission in subreddit.new(limit=None):
if re.search(pattern, submission.link_flair_text):
if not getDatabase().search(where('submission_id') == submission.id):
saveSubmission(submission.id)
postTweet(submission)
print('Found Post: ' + submission.id)
print(submission.title)
else:
print('No Post Found')
# usage: getSubmissions()
Day 4: Corners as round as Kim's...
The code below is written in Swift and as of Xcode 11.5 and iOS 13.5.x is still correct.
extension UIView {
func round(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: corners, cornerRadii:CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
// usage: view.round(corners: .allCorners, radius: 14)
Day 5: Cutting a transparent hole in a UIVisualEffectView
The code below is written in Objective-C and as of Xcode 11.5 and iOS 13.5.x is still correct.
-(void) cut:(UIView *)view rect:(CGRect)rect usesRadius:(BOOL)usesRadius radius:(CGFloat)radius {
UIBezierPath *path = [UIBezierPath bezierPathWithRect:view.bounds];
UIBezierPath *hole = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:usesRadius ? radius : 0];
[path appendPath:hole];
[path setUsesEvenOddFillRule:YES];
CAShapeLayer *mask = [[CAShapeLayer alloc] init];
[mask setFillRule:kCAFillRuleEvenOdd];
[mask setFillColor:[[UIColor blackColor] CGColor]];
[mask setPath:[path CGPath]];
[view.layer setMask:mask];
}
// usage: [self cut:someView rect:CGRectMake(8, 8, 20, 20) usesRadius:YES radius:8];
The idea for this came when looking at Apple's Control Centre toggles, most have a transparent toggle with a slight blur, writing this in Carbonite (a project of mine) lead to this code snippet.
Day 6: Logging NSString objects to a file
The code below is written in Objective-C and as of Xcode 11.5 and iOS 13.5.x is still correct.
-(void) log:(NSString *)string {
NSString *path = // path goes here;
if(![[NSFileManager defaultManager] fileExistsAtPath:path]) {
[[NSData data] writeToFile:path atomically:YES];
}
NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:path];
[handle truncateFileAtOffset:[handle seekToEndOfFile]];
[handle writeData:[string dataUsingEncoding:NSUTF8StringEncoding]];
[handle closeFile];
}
// usage: [self log:@"Look at me! I'm your new logging method."];
Day 7: Using MPMusicPlayerController methods
The code below is written in Objective-C and as of Xcode 11.5 and iOS 13.5.x is still correct.
// Creating an MPMusicPlayerController instance
MPMusicPlayer *musicPlayerController = [MPMusicPlayerController systemMusicPlayer];
// Getting an array of all songs
NSArray <MPMediaItem *> *songs = [[MPMediaQuery songsQuery] items];
// Getting song information (below is if songs.count > 0)
NSString *songTitle = [songs[0] valueForKey:MPMediaItemPropertyTitle];
// For more keys visit this link to view the official documentation:
// https://developer.apple.com/documentation/mediaplayer/mpmediaitem?language=objc
// Play a song
MPMediaItem *songToPlay = songs[0]
[musicPlayerController setNowPlayingItem:item];
[musicPlayerController prepareToPlay];
[musicPlayerController play];
// Play
[musicPlayerController play];
// Pause
[musicPlayerController pause];
// Skip
[musicPlayerController skipToNextItem];
// Previous
[musicPlayerController skipToPreviousItem];
Day 8: Writing an API wrapper for weatherstack.com
The code below is written in Objective-C and as of Xcode 11.5 and iOS 13.5.x is still correct.
// WeatherData.h
@interface WeatherData : NSObject
// REQUEST
@property (nonatomic, strong) NSString *type;
@property (nonatomic, strong) NSString *query;
@property (nonatomic, strong) NSString *language;
@property (nonatomic, strong) NSString *unit;
// LOCATION
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *country;
@property (nonatomic, strong) NSString *region;
@property (nonatomic, strong) NSString *lat;
@property (nonatomic, strong) NSString *lon;
@property (nonatomic, strong) NSString *timezone_id;
@property (nonatomic, strong) NSString *localtime;
@property (nonatomic, strong) NSString *localtime_epoch;
@property (nonatomic, strong) NSString *utc_offset;
// CURRENT
@property (nonatomic, strong) NSString *observation_time;
@property (nonatomic, strong) NSString *temperature;
@property (nonatomic, strong) NSString *weather_code;
@property (nonatomic, strong) NSArray <NSString *> *weather_icons;
@property (nonatomic, strong) NSArray <NSString *> *weather_descriptions;
@property (nonatomic, strong) NSNumber *wind_speed;
@property (nonatomic, strong) NSNumber *wind_degree;
@property (nonatomic, strong) NSNumber *wind_dir;
@property (nonatomic, strong) NSNumber *pressure;
@property (nonatomic, strong) NSNumber *precip;
@property (nonatomic, strong) NSNumber *humidity;
@property (nonatomic, strong) NSNumber *cloudcover;
@property (nonatomic, strong) NSNumber *feelslike;
@property (nonatomic, strong) NSNumber *uv_index;
@property (nonatomic, strong) NSNumber *visibility;
@property (nonatomic, assign) BOOL is_day;
-(id) initWithJSON:(NSData *)json;
@end
// WeatherData.m
#import "WeatherData.h"
@implementation WeatherData
-(id) initWithJSON:(NSData *)json {
if(self = [super init]) {
NSError *error;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
if(error) {
NSLog(@"NSJSONSerialization failed with error: %@", [error localizedDescription]);
return self;
}
if([jsonObject isKindOfClass:[NSDictionary class]]) {
id requestDictionary = [jsonObject objectForKey:@"request"];
if([requestDictionary isKindOfClass:[NSDictionary class]]) {
id type = [requestDictionary objectForKey:@"type"];
if([type isKindOfClass:[NSString class]]) {
_type = type;
}
id query = [requestDictionary objectForKey:@"query"];
if([query isKindOfClass:[NSString class]]) {
_query = query;
}
id language = [requestDictionary objectForKey:@"type"];
if([language isKindOfClass:[NSString class]]) {
_language = language;
}
id unit = [requestDictionary objectForKey:@"unit"];
if([unit isKindOfClass:[NSString class]]) {
_unit = unit;
}
}
id locationDictionary = [jsonObject objectForKey:@"location"];
if([locationDictionary isKindOfClass:[NSDictionary class]]) {
id name = [locationDictionary objectForKey:@"name"];
if([name isKindOfClass:[NSString class]]) {
_name = name;
}
id country = [locationDictionary objectForKey:@"country"];
if([country isKindOfClass:[NSString class]]) {
_country = country;
}
id region = [locationDictionary objectForKey:@"region"];
if([region isKindOfClass:[NSString class]]) {
_region = region;
}
id lat = [locationDictionary objectForKey:@"lat"];
if([lat isKindOfClass:[NSString class]]) {
_lat = lat;
}
id lon = [locationDictionary objectForKey:@"lon"];
if([lon isKindOfClass:[NSString class]]) {
_lon = lon;
}
id timezone_id = [locationDictionary objectForKey:@"timezone_id"];
if([timezone_id isKindOfClass:[NSString class]]) {
_timezone_id = [timezone_id stringByReplacingOccurrencesOfString:@""];
}
id localtime = [locationDictionary objectForKey:@"localtime"];
if([localtime isKindOfClass:[NSString class]]) {
_localtime = localtime;
}
_localtime_epoch = [NSNumber numberWithInt:[[locationDictionary objectForKey:@"localtime_epoch"] intValue]];
id utc_offset = [locationDictionary objectForKey:@"utc_offset"];
if([utc_offset isKindOfClass:[NSString class]]) {
_utc_offset = utc_offset;
}
}
id currentDictionary = [jsonObject objectForKey:@"current"];
if([currentDictionary isKindOfClass:[NSDictionary class]]) {
id observation_time = [locationDictionary objectForKey:@"observation_time"];
if([observation_time isKindOfClass:[NSString class]]) {
_observation_time = observation_time;
}
_temperature = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"temperature"] intValue]];
_weather_code = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"weather_code"] intValue]];
id weather_icons = [currentDictionary objectForKey:@"weather_icons"];
if([weather_icons isKindOfClass:[NSArray class]]) {
_weather_icons = weather_icons;
}
id weather_descriptions = [currentDictionary objectForKey:@"weather_descriptions"];
if([weather_descriptions isKindOfClass:[NSArray class]]) {
_weather_descriptions = weather_descriptions;
}
_wind_speed = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"wind_speed"] intValue]];
_wind_degree = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"weather_degree"] intValue]];
id wind_dir = [currentDictionary objectForKey:@"wind_dir"];
if([wind_dir isKindOfClass:[NSString class]]) {
_wind_dir = wind_dir;
}
_pressure = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"pressure"] intValue]];
_precip = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"precip"] intValue]];
_humidity = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"humidity"] intValue]];
_cloudcover = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"cloudcover"] intValue]];
_feelslike = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"feelslike"] intValue]];
_uv_index = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"uv_index"] intValue]];
_visibility = [NSNumber numberWithInt:[[currentDictionary objectForKey:@"visibility"] intValue]];
_visibility = [NSNumber numberWithBool:[[currentDictionary objectForKey:@"is_day"] boolValue]];
}
} else {
NSLog(@"Data is not a dictionary");
}
} return self;
}
@end
// WeatherAPI.h
#import <CoreLocation/CoreLocation.h>
#import "WeatherData.h"
@interface WeatherAPI : NSObject
+(WeatherAPI *)sharedInstance;
-(void) fetchWeatherForLocation:(CLLocation *)location completion:(void(^)(WeatherData *weatherData))completion failure:(void(^)(NSError *error))failure;
@end
// WeatherAPI.m
#import "WeatherAPI.h"
@implementation WeatherAPI
+(WeatherAPI *) sharedInstance {
static WeatherAPI *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[WeatherAPI alloc] init];
});
return sharedInstance;
}
-(void) fetchWeatherForLocation:(CLLocation *)location completion:(void(^)(WeatherData *weatherData))completion failure:(void(^)(NSError *error))failure {
float latitude = location.coordinate.latitude;
float longitude = location.coordinate.longitude;
NSString *urlString = [NSString stringWithFormat:@"http://api.weatherstack.com/current?access_key=%@&query=%f,%f&units=%@", @"35c9be78ab2dcc41d19c5879147894d0", latitude, longitude, @"m"];
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:urlString];
[[session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error) {
failure(error);
} else {
WeatherData *weather = [[WeatherData alloc] initWithJSON:data];
completion(weather);
}
}] resume];
}
@end
Day 9: Convert NSTimeInterval to NSString
The code below is written in Objective-C and as of Xcode 11.5 and iOS 13.5.x is still correct.
-(NSString *) string:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
// hours: long hours (interval / 3600);
long minutes = interval % 60;
long seconds = (interval / 60) % 60;
return [NSString stringWithFormat:@"%0.2ld:%0.2ld", minutes, seconds];
}
Day 10: Convert NSDate to NSString and vice versa
The code below is written in Objective-C and as of Xcode 11.5 and iOS 13.5.x is still correct.
-(NSString *) stringFromDate:(NSDate *)date {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"dd/MM/yyyy h:mma"];
return [formatter stringFromDate:date];
}
// returns 15/05/2020 12:00am (or whatever the provided NSDate contains)
-(NSDate *) dateFromString:(NSString *)string {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"dd/MM/yyyy h:mma"];
return [formatter dateFromString:string];
}
Day 11: Achieving different blurs in Logos
The code below is written in Objective-C (Logos) and as of iOS 13.5.x is still correct.
@interface MTMaterialView : UIView
+(id) materialViewWithRecipe:(long long)arg1 configuration:(long long)arg2;
@end
/* usage:
MTMaterialView *blurView = [MTMaterialView materialViewWithRecipe:0 configuration:0];
[blurView setFrame:CGRectMake(x, y, w, h)];
[self addSubview:blurView];
*/
@interface _UIBackdropView : UIView
-(id) initWithFrame:(CGRect)arg1 autosizesToFitSuperview:(BOOL)arg2 settings:(id)arg3;
-(id) initWithPrivateStyle:(int)arg1;
-(id) initWithSettings:(id)arg1;
-(id) initWithStyle:(int)arg1;
// Some methods here may cause crashes and should be removed, test by running each method if wanting to use them.
-(void) setBlurFilterWithRadius:(float)arg1 blurQuality:(id)arg2 blurHardEdges:(int)arg3;
-(void) setBlurFilterWithRadius:(float)arg1 blurQuality:(id)arg2;
-(void) setBlurHardEdges:(int)arg1;
-(void) setBlurQuality:(id)arg1;
-(void) setBlurRadius:(float)arg1;
-(void) setBlurRadiusSetOnce:(BOOL)arg1;
-(void) setBlursBackground:(BOOL)arg1;
-(void) setBlursWithHardEdges:(BOOL)arg1;
@end
@interface _UIBackdropViewSettings : NSObject
+(id) settingsForStyle:(int)arg1;
@end
/* usage:
_UIBackdropView *blurView = [[_UIBackdropView alloc] initWithStyle:2060];
[blurView setFrame:CGRectMake(x, y, w, h)];
[blurView setBlurRadiusSetOnce:NO];
[blurView setBlurRadius:4.0];
[blurView setBlurHardEdges:2];
[blurView setBlursWithHardEdges:YES];
[blurView setBlurQuality:@"default"];
[view addSubview:blurView];
*/
Some methods may no longer work in newer iOS versions, if this is the case ensure you remove them. The class itself does still work.
UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular];
[blurView setFrame:CGRectMake(x, y, w, h)];
[self addSubview:blurView];
Day 12: NSFileManager and its many uses
The code below is written in Swift and as of Xcode 11.5 and iOS 13.5.x is still correct.
// Check if a file or folder exists
let fileExists = FileManager.default.fileExists(atPath: "PATH")
var isDirectory = false
let folderExists = FileManager.default.fileExists(atPath: "PATH", isDirectory: &isDirectory)
// Copy item from one path to another
FileManager.default.copyItem(atPath: "PATH", toPath: "PATH")
// Move item from one path to another
FileManager.default.moveItem(atPath: "PATH", toPath: "PATH")
// Remove item from the provided path
FileManager.default.removeItem(atPath: "PATH")
// List an array of contents from the provided path
let filesArray = FileManager.default.contentsOfDirectory(atPath: "PATH")
// Create a symbolic link
FileManager.default.createSymbolicLink(atPath: "PATH", withDestinationPath: "PATH")
// Get the name of a file or folder at the provided path
let fileName = FileManager.default.displayName(atpath: "PATH")
Day 13: Displaying a window above SpringBoard (iOS 13 and below).
The code below is written in Objective-C and as of iOS 13.5.x is still correct.
// Our window will be called 'window' for this snippet.
-(void) showWindow {
[window setHidden:NO];
if(@available(iOS 13.0, *)) {
if(!window.windowScene || window.windowScene.activationState != UISceneActivationStateForegroundActive) {
for(UIScene *scene in [[UIApplication sharedApplication] connectedScenes]) {
if(scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) {
window.windowScene = (UIWindowScene *)scene;
break;
}
}
}
} else {
// Normal iOS 12 and below methods work here
}
}
Remember to set the windowLevel
, a good level is 1089 which shows the window above everything while not being too high.
Day 14: Compressing and decompressing data
The code below is written in Swift and as of iOS 13.5.x is still correct.
// Compress
do {
let compressed = try (data as NSData).compress(using: .lzma)
// Save compressed data
} catch {
print(error.localizedDescription)
}
// Decompress
do {
let decompressed = try (data as NSData).decompress(using: .lzma)
// Use decompressed data
} catch {
print(error.localizedDescription)
}
Day 15: Getting an iOS device's UDID (Jailbroken)
The code below is written in Objective-C and as of iOS 12.x is still correct.
// main.m
#include <stdio.h>
OBJC_EXTERN CFStringRef MGCopyAnswer(CFStringRef key) WEAK_IMPORT_ATTRIBUTE;
NSString *udid() {
CFStringRef udid = MGCopyAnswer(CFSTR("UniqueDeviceID"));
return (NSString *)CFBridgingRelease(udid);
}
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_CYAN "\x1b[36m"
#define ANSI_COLOR_RESET "\x1b[0m"
int main(int argc, char *argv[], char *envp[]) {
NSError *error;
[udid() writeToFile:@"/var/mobile/udid.txt" atomically:NO encoding:NSStringEncodingConversionAllowLossy error:&error];
if(error) {
printf("Error: %s%s%s\n", ANSI_COLOR_RED, [error.localizedDescription UTF8String], ANSI_COLOR_RESET);
} else {
printf("UDID: %s%s%s\n", ANSI_COLOR_CYAN, [udid() UTF8String], ANSI_COLOR_RESET);
printf("%s%s%s\n", ANSI_COLOR_RED, [@"Saved to '/var/mobile/udid.txt'" UTF8String], ANSI_COLOR_RESET);
} return 0;
}
<!-- entitlements.xml -->
<?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>http://com.apple.private.MobileGestalt.AllowedProtectedKeys</key>
<true/>
<key>http://com.apple.private.security.no-container</key>
<true/>
</dict>
</plist>
Last updated
Was this helpful?