💻
Reimagine
  • Reimagine
  • Start using Theos
    • About Theos
    • Installing Theos
    • Theos FAQ
  • Create a Tweak
    • Create a Project
  • Documentation
    • Carbonite Modules
    • Corners as round as Kim's
  • Once Upon A Time
    • What?
  • Code Snippets
    • #100DaysOfCode - Antique
Powered by GitBook
On this page
  • Day 1: Distance between two CLLocation objects.
  • Day 2: Generating a random password
  • Day 3: Tweet a Reddit post with a specific flair
  • Day 4: Corners as round as Kim's...
  • Day 5: Cutting a transparent hole in a UIVisualEffectView
  • Day 6: Logging NSString objects to a file
  • Day 7: Using MPMusicPlayerController methods
  • Day 8: Writing an API wrapper for weatherstack.com
  • Day 9: Convert NSTimeInterval to NSString
  • Day 10: Convert NSDate to NSString and vice versa
  • Day 11: Achieving different blurs in Logos
  • Day 12: NSFileManager and its many uses
  • Day 13: Displaying a window above SpringBoard (iOS 13 and below).
  • Day 14: Compressing and decompressing data
  • Day 15: Getting an iOS device's UDID (Jailbroken)

Was this helpful?

  1. Code Snippets

#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>
PreviousWhat?

Last updated 5 years ago

Was this helpful?

This produces a clean corner compared to the normal cornerRadius which does not perform so well. from on Twitter. Taken from my writeup .

The code above is the first available wrapper for written in Objective-C. Developed by me, .

Additional styles and further documentation can be found .

Additional styles and further documentation can be found .

Further documentation can be found .

Example
@nathangitter
here
https://weatherstack.com
@antique_dev
here
here
here