Test User

Send a Message

Blogs RSS


BV Testing for
iPhone/iPad


BV Testing for
Android


Friends
This user does not have any friends yet...


About Me
My Store Desc

https://discoveryprovider.audius.co/v1/users/nlGNe/tracks?app_name=thechopstars

https://anchor.fm/s/31ae2a0/podcast/rss... Read More
 

BV Testing


https://www.blackvibes.com/bvtesting
 

Test Blog Name 2


   

Today it's been exactly five years since this website first launched, and what a journey it has been! When I started this website after having published weekly articles on Medium for a few months, I honestly had no idea what to expect. I wasn't even sure if anyone would even find the site to begin with, let alone be interested in coming back week after week to read my new articles.
But now, five years later, and with over 550 articles and 115 podcast episodes published, this website has been visited by over a million Swift developers from all around the world, and hundreds of thousands of people come back to read new articles and listen to new podcast episodes every single month. To see this website grow like that has been absolutely incredible, and I'm eternally grateful for all of the amazing support that you - the Swift community - have given me over these first five years.
During these first few years, the amount of time that I've been able to spend working on my articles and podcast episodes has varied quite a lot. In the beginning, I was simply working on Swift by Sundell during my spare time, as a hobby project, and I had no plans or intentions to ever scale the project much beyond that. But at the same time, the website kept growing, and so did my ambitions, and at the start of 2019 (two years after the initial launch) I made the rather bold decision to turn Swift by Sundell into my full-time job.
In retrospect, I'm incredibly happy that I made that decision, not only because it enabled me to produce a much larger number of more detailed articles, and spend more time on podcast editing to make each episode sound great - but also because it led to the creation of Ink, Plot, and Publish, and the current iteration of this website which uses those tools to produce a fast, easy to use, statically generated site that I'm super proud of.
Working full-time on your own projects, as amazing as it in many ways is, also comes with quite a few downsides, though. In particular, I really started to miss working with other people, to be a part of a team, and to do actual iOS and macOS app development. Building Publish and my other open source tools was a lot of fun, and involved solving a ton of interesting problems, but it just wasn't the same as working on complex app projects with dedicated co-workers.
So in 2020 I decided to start freelancing again, part-time, while still keeping Swift by Sundell as my main, full-time job - which worked out great. In fact, it worked out so great that I started taking on more freelancing work throughout 2021, and for a while, I was incredibly happy with how my work was progressing. Business was great, with income from both this website's sponsorships and from my freelancing work, I got to work on some incredibly cool projects, plus those projects gave me such a huge amount of inspiration for both my articles and podcast episodes. It all turned out to be one big, positive feedback loop.
However, towards the end of 2021, I started to feel that something was wrong. I very often felt incredibly stressed, and sometimes even deeply disappointed in myself for not writing enough articles, for not publishing podcast episodes frequently enough, for not reviewing open source pull requests fast enough, or for not working enough hours on a given project.
Looking back, it's quite obvious what had happened. As I kept constantly expanding all of my projects and client work over time, I had ended up with more or less two full-time jobs, and it became clear that I was at the edge (or, some may say, even past the edge) of being burned out. Something had to change.
So, at the beginning of this year, I sat down and started making a plan. I knew that I didn't want to stop doing client work (I still work on some really nice projects with incredible teams), and I also knew that I didn't want to quit working on this website, the podcast, Stacktrace (my other podcast), or my open source projects. So I just needed to come up with some kind of compromise, a schedule that would let me keep working on all of those things that I'm super passionate about, while also making that schedule much more sustainable and healthy.
What I've come up with will likely disappoint some of you, since it does involve a reduction of the amount of time that I'll be able to spend on Swift by Sundell going forward (and the number of articles and podcast episodes that I'll be able to make as a result), but I want to make it crystal clear that I'm making these changes because I want to keep working on Swift by Sundell for many more years to come. I love this website and the wonderful community that exists around Swift and Apple's platforms, and I want to continue contributing to that community as much as I possibly can far into the future.
So, what changes am I making? First, I'm removing all sorts of publishing schedules, and will instead post new articles and podcast episodes on a more infrequent basis. While I'm aiming to publish at least one new article and one podcast episode per month, there might occasionally be some periods of time where not much is happening on this website, but that doesn't mean that I've abandoned it, I might just be busy with other work. I've always prioritized quality over quantity, and I'd much rather take my time writing a really great article than rush one out just to meet a specific schedule.
Next, I'm removing all ads from the website, starting next week, on the 9th of May. That's right, you'll soon be able to enjoy all of this website's hundreds of articles and all of my Discover guides completely ad-free, all free of charge. While I might occasionally publish a (clearly marked) sponsored post, and there will still be sponsorships on the podcast, I want to turn my articles back to what they started out as - a way for me to share my thoughts and learnings with the community without any kind of commercial motives or pressure.
I truly appreciate all of the sponsors that have advertised on this website over the past three and a half years, and I'm not saying that I'll never do website sponsorships again, but not having to book, schedule and manage weekly website sponsorships is going to free up a lot of time (and remove a ton of stress), so it feels like the right move to make at this point.
So, to sum up, Swift by Sundell is here to stay, and while you'll see new content published on a more infrequent basis going forward, you'll be able to freely access all of this site's huge collection of articles completely ad-free. I truly believe that this is the best path forward, both for Swift by Sundell and for me personally, and I hope you'll keep joining me on this journey for a long time to come.
Thanks so much for reading, happy fifth birthday to Swift by Sundell, and here's to five more years of articles, podcasts, and more!

via: https://www.swiftbysundell.com/special/five-year


Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

   

Simon Støvring returns to the show to talk about how he built his new text editor Runestone, how to effectively manage an app's settings, performance tuning, and implementing an app's core logic as a stand-alone framework.
Sponsors

  • Judo: Quickly build native, server-driven UI for iOS and Android, and publish instantly, without having to submit updates to the App Store. Try it for free today, by going to judo.app/sundell.
  • Bitrise: Rock-solid continuous integration for your Swift project, which now offers 50% faster builds and ad-ons for things like automatic deployment. Go to bitrise.io/swift to get started for free.Links
  • Simon on Twitter
  • John on Twitter
  • Runestone
  • Scriptable
  • Data Jar
  • Jayson
  • Visual Studio Code
  • Working Copy
  • UserDefaults
  • Property wrappers
  • SwiftUI's state management system
  • UITextView
  • SwiftUI's TextEditor
  • TextKit
  • CoreText
  • UITextInput
  • JavascriptCore
  • Publish
  • Managing dependencies using Swift Package Manager
  • Simon's website
  • Intro and outro music by Dariusz Dziuk

    via: https://www.swiftbysundell.com/podcast/11


  • Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

    Type placeholders in Swift

       

    Swift's type inference capabilities have been a very core part of the language since the very beginning, and heavily reduces the need for us to manually specify types when declaring variables and properties that have default values. For example, the expression var number = 7 doesn't need to include any type annotations, since the compiler is able to infer that the value 7 is an Int and that our number variable should be typed accordingly.
    Swift 5.6, which was released as part of Xcode 13.3, continues to expand these type inference capabilities by introducing the concept of "type placeholders", which can come very much in handy when working with collections and other generic types.
    For example, let's say that we wanted to create an instance of Combine's CurrentValueSubject with a default integer value. An initial idea on how to do just that might be to simply pass our default value to that subject's initializer, and then store the result in a local let (just like when creating a plain Int value). However, doing so gives us the following compiler error:
    // Error: "Generic parameter 'Failure' could not be inferred"
    let counterSubject = CurrentValueSubject(0)That's because CurrentValueSubject is a generic type that needs to be specialized with not just an Output type, but also with a Failure type - which is the type of error that the subject is capable of throwing.
    Since we don't want our subject to throw any errors in this case, we'll give it the failure type Never (which is a common convention when using both Combine and Swift concurrency). But in order to do that, prior to Swift 5.6, we would need to explicitly specify our Int output type as well - like this:
    let counterSubject = CurrentValueSubject<Int, Never>(0)Starting in Swift 5.6, though, that's no longer the case - as we can now use a type placeholder for our subject's output type, which lets us once again leverage the compiler to automatically infer that type for us, just like when declaring a plain Int value:
    let counterSubject = CurrentValueSubject<_, Never>(0)That's nice, but it's arguably not the biggest improvement in the world. After all, we're only saving two characters by replacing Int with _, and it's not like manually specifying a simple type like Int was something problematic to begin with.
    But let's now take a look at how this feature scales to more complex types, which is where it really starts to shine. For example, let's say that our project contains the following function that lets us load a user-annotated PDF file:
    func loadAnnotatedPDF(named: String) -> Resource<PDF<UserAnnotations>> {
    ...
    }The above function uses a quite complex generic as its return type, which might be because we're reusing our Resource type across multiple domains, and because we've opted to use phantom types to specify what kind of PDF that we're currently dealing with.
    Now let's take a look at what our CurrentValueSubject-based code from before would look like if we were to call the above function when creating our subject, rather than just using a simple integer:
    // Before Swift 5.6:
    let pdfSubject = CurrentValueSubject<Resource<PDF<UserAnnotations>>, Never>(
    loadAnnotatedPDF(named: name)
    )

    // Swift 5.6:
    let pdfSubject = CurrentValueSubject<_, Never>(
    loadAnnotatedPDF(named: name)
    )That's quite a huge improvement! Not only does the Swift 5.6-based version save us some typing, but since the type of pdfSubject is now derived completely from the loadAnnotatedPDF function, that'll likely make iterating on that function (and its related code) much easier - since there will be fewer manual type annotations that will need to be updated if we ever change that function's return type.
    It's worth pointing out, though, that there's another way to leverage Swift's type inference capabilities in situations like the one above - and that's to use a type alias, rather than a type placeholder. For example, here's how we could define an UnfailingValueSubject type alias, which we'll be able to use to easily create subjects that aren't capable of throwing any errors:
    typealias UnfailingValueSubject<T> = CurrentValueSubject<T, Never>With the above in place, we'll now be able to create our pdfSubject without any kind of generic type annotations at all - since the compiler is able to infer what type that T refers to, and since the failure type Never has been hard-coded into our new type alias:
    let pdfSubject = UnfailingValueSubject(loadAnnotatedPDF(named: name))That doesn't mean that type aliases are universally better than type placeholders, though, since if we were to define new type aliases for each particular situation, then that could also make our code base much more complicated. Sometimes, specifying everything inline (like when using a type placeholder) is definitely the way to go, as that lets us define expressions that are completely self-contained.
    Before we wrap things up, let's also take a look at how type placeholders can be used with collection literals - for example when creating a dictionary. Here, we've opted to manually specify our dictionary's Key type (in order to be able to use dot-syntax to refer to an enum's various cases), while using a type placeholder for that dictionary's values:
    enum UserRole {
    case local
    case remote
    }

    let latestMessages: [UserRole: _] = [
    .local: "",
    .remote: ""
    ]So that's type placeholders - a new feature introduced in Swift 5.6, which will likely be really useful when dealing with slightly more complex generic types. It's worth pointing out, though, that these placeholders can only be used at call sites, not when specifying the return types of either functions or computed properties.
    I hope you found this article useful, and feel free to let me know if you have any questions, comments, or feedback - either via Twitter or email.
    Thanks for reading!

    via: https://www.swiftbysundell.com/articles/type-placeholders-in-swif


    Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

       

    Sommer Panage returns to the show to discuss Apple's various accessibility APIs and tools, how to incorporate accessibility support into a team's overall development workflow, and what it was like being an engineering manager at Apple.
    Sponsors

  • Emerge Tools: Optimize your app's startup time, binary size, and overall performance using Emerge's advanced app optimization and monitoring tools. Get started at emergetools.com.
  • Bitrise: Rock-solid continuous integration for your Swift project, which now offers 50% faster builds and ad-ons for things like automatic deployment. Go to bitrise.io/swift to get started for free.Links
  • VoiceOver
  • Voice Control
  • Dynamic Type
  • PSPDFKit's blog post about Dynamic Type
  • Defining accessibility labels
  • Accessibility traits
  • WWDC session about custom accessibility actions
  • WWDC session about using AXCustomContent
  • isReduceMotionEnabled
  • prefersCrossFadeTransitions
  • shouldDifferentiateWithoutColor
  • SwiftUI's accessibilityElement modifier
  • Audio graphs
  • Intro and outro music by Dariusz Dziuk

    via: https://www.swiftbysundell.com/podcast/11


  • Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

    Abstract types and methods in Swift

       

    In object-oriented programming, an abstract type provides a base implementation that other types can inherit from in order to gain access to some kind of shared, common functionality. What separates abstract types from regular ones is that they're never meant to be used as-is (in fact, some programming languages even prevent abstract types from being instantiated directly), since their sole purpose is to act as a common parent for a group of related types.
    For example, let's say that we wanted to unify the way we load certain types of models over the network, by providing a shared API that we'll be able to use to separate concerns, to facilitate dependency injection and mocking, and to keep method names consistent throughout our project.
    One abstract type-based way to do that would be to use a base class that'll act as that shared, unified interface for all of our model-loading types. Since we don't want that class to ever be used directly, we'll make it trigger a fatalError if its base implementation is ever called by mistake:
    class Loadable<Model> {
    func load(from url: URL) async throws -> Model {
    fatalError("load(from:) has not been implemented")
    }
    }Then, each Loadable subclass will override the above load method in order to provide its loading functionality - like this:
    class UserLoader: Loadable<User> {
    override func load(from url: URL) async throws -> User {
    ...
    }
    }If the above sort of pattern looks familiar, it's probably because it's essentially the exact same sort of polymorphism that we typically use protocols for in Swift. That is, when we want to define an interface, a contract, that multiple types can conform to through distinct implementations.
    Protocols do have a significant advantage over abstract classes, though, in that the compiler will enforce that all of their requirements are properly implemented - meaning we no longer have to rely on runtime errors (such as fatalError) to guard against improper use, since there's no way to instantiate a protocol by itself.
    So here's what our Loadable and UserLoader types from before could look like if we were to go the protocol-oriented route, rather than using an abstract base class:
    protocol Loadable {
    associatedtype Model
    func load(from url: URL) async throws -> Model
    }

    class UserLoader: Loadable {
    func load(from url: URL) async throws -> User {
    ...
    }
    }Note how we're now using an associated type to enable each Loadable implementation to decide what exact Model that it wants to load - which gives us a nice mix between full type safety and great flexibility.
    So, in general, protocols are definitely the preferred way to declare abstract types in Swift, but that doesn't mean that they're perfect. In fact, our protocol-based Loadable implementation currently has two main drawbacks:

  • First, since we had to add an associated type to our protocol in order to keep our setup generic and type-safe, that means that Loadable can no longer be referenced directly.
  • And second, since protocols can't contain any form of storage, if we wanted to add any stored properties that all Loadable implementations could make use of, we'd have to re-declare those properties within every single one of those concrete implementations.That property storage aspect is really a huge advantage of our previous, abstract class-based setup. So if we were to revert Loadable back to a class, then we'd be able to store all objects that our subclasses would need right within our base class itself - removing the need to duplicate those properties across multiple types:
    class Loadable<Model> {
    let networking: Networking
    let cache: Cache<URL, Model>

    init(networking: Networking, cache: Cache<URL, Model>) {
    self.networking = networking
    self.cache = cache
    }

    func load(from url: URL) async throws -> Model {
    fatalError("load(from:) has not been implemented")
    }
    }

    class UserLoader: Loadable<User> {
    override func load(from url: URL) async throws -> User {
    if let cachedUser = cache.value(forKey: url) {
    return cachedUser
    }

    let data = try await networking.data(from: url)
    ...
    }
    }So, what we're dealing with here is essentially a classic trade-off scenario, where both approaches (abstract classes vs protocols) give us a different set of pros and cons. But what if we could combine the two to sort of get the best of both worlds?
    If we think about it, the only real issue with the abstract class-based approach is that fatalError that we had to add within the method that each subclass is required to implement, so what if we were to use a protocol just for that specific method? Then we could still keep our networking and cache properties within our base class - like this:
    protocol LoadableProtocol {
    associatedtype Model
    func load(from url: URL) async throws -> Model
    }

    class LoadableBase<Model> {
    let networking: Networking
    let cache: Cache<URL, Model>

    init(networking: Networking, cache: Cache<URL, Model>) {
    self.networking = networking
    self.cache = cache
    }
    }The main disadvantage of that approach, though, is that all concrete implementations will now have to both subclass LoadableBase and declare that they conform to our new LoadableProtocol:
    class UserLoader: LoadableBase<User>, LoadableProtocol {
    ...
    }That might not be a huge issue, but it does arguably make our code a bit less elegant. The good news, though, is that we can actually solve that issue by using a generic type alias. Since Swift's composition operator, &, supports combining a class with a protocol, we can re-introduce our Loadable type as a combination between LoadableBase and LoadableProtocol:
    typealias Loadable<Model> = LoadableBase<Model> & LoadableProtocolThat way, concrete types (such as UserLoader) can simply declare that they're Loadable-based, and the compiler will ensure that all such types implement our protocol's load method - while still enabling those types to use the properties declared within our base class as well:
    class UserLoader: Loadable<User> {
    func load(from url: URL) async throws -> User {
    if let cachedUser = cache.value(forKey: url) {
    return cachedUser
    }

    let data = try await networking.data(from: url)
    ...
    }
    }Neat! The only real disadvantage of the above approach is that Loadable still can't be referenced directly, since it's still partially a generic protocol under the hood. That might not actually be an issue, though - and if that ever becomes the case, then we could always use techniques such as type erasure to get around such problems.
    Another slight caveat with our new type alias-based Loadable setup is that such combined type aliases cannot be extended, which could become an issue if we wanted to provide a few convenience APIs that we don't want to (or can't) implement directly within our LoadableBase class.
    One way to address that issue, though, would be to declare everything that's needed to implement those convenience APIs within our protocol, which would then enable us to extend that protocol by itself:
    protocol LoadableProtocol {
    associatedtype Model

    var networking: Networking { get }
    var cache: Cache<URL, Model> { get }

    func load(from url: URL) async throws -> Model
    }

    extension LoadableProtocol {
    func loadWithCaching(from url: URL) async throws -> Model {
    if let cachedModel = cache.value(forKey: url) {
    return cachedModel
    }

    let model = try await load(from: url)
    cache.insert(model, forKey: url)
    return model
    }
    }So that's a few different ways to use abstract types and methods in Swift. Subclassing might not currently be as popular as it once was (and remains to be within other programming languages), but I still think these sorts of techniques are great to have within our overall Swift development toolbox.
    If you have any questions, comments, or feedback, then feel free to reach out via either Twitter or email.
    Thanks for reading!

    via: https://www.swiftbysundell.com/articles/abstract-types-and-method


  • Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

    Marketing For Dummies Part 2

       

    Marketing For Dummies Part 2

    Sean Garvey sits down with musical artist Marcel Alexander to discuss the different kinds of marketing strategies for content creators. Alexander goes more in depth about using social media as a tool for marketing purposes and how his level of marketing expertise made him successful as a creator. Plus, Garvey speaks to Alexander about his involvement in the latest critically acclaimed documentary The Inside Story.

    For more info about Marcel Alexander:
    http://www.livelitemarcel.com

    More information about The Inside Story: https://www.tntdrama.com/theinsidestory

    Follow Sean Garvey on IG: https://www.instagram.com/seangarveyatl

    To create your own app:
    https://www.bvmobileapps.com

    ?? Music by: J. Keys (Anonymous Records) - @jkeysmusic



    via: https://audiomack.com/bvmobileapps/song/marketing-strategies-for-content-creator


    Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

    Marketing For Dummies

       

    Marketing For Dummies

    Sean Garvey sits down with musical artist Marcel Alexander to discuss the different kinds of marketing strategies for content creators. Alexander goes more in depth about using social media as a tool for marketing purposes and how his level of marketing expertise made him successful as a creator. Plus, Garvey speaks to Alexander about his involvement in the latest critically acclaimed documentary The Inside Story.

    For more info about Marcel Alexander:
    http://www.livelitemarcel.com

    More information about The Inside Story: https://www.tntdrama.com/theinsidestory

    Follow Sean Garvey on IG: https://www.instagram.com/seangarveyatl

    To create your own app:
    https://www.bvmobileapps.com

    ?? Music by: J. Keys (Anonymous Records) - @jkeysmusic



    via: https://audiomack.com/bvmobileapps/song/marketing-strategies-for-content-creator


    Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

    Marketing Strategies for Content Creators

       

    Marketing Strategies for Content Creators

    Sean Garvey sits down with musical artist Marcel Alexander to discuss the different kinds of marketing strategies for content creators. Alexander goes more in depth about using social media as a tool for marketing purposes and how his level of marketing expertise made him successful as a creator. Plus, Garvey speaks to Alexander about his involvement in the latest critically acclaimed documentary The Inside Story.

    For more info about Marcel Alexander:
    http://www.livelitemarcel.com

    More information about The Inside Story: https://www.tntdrama.com/theinsidestory

    Follow Sean Garvey on IG: https://www.instagram.com/seangarveyatl

    To create your own app:
    https://www.bvmobileapps.com



    via: https://audiomack.com/bvmobileapps/song/marketing-strategies-for-content-creator


    Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

    Top 3 Tips for Running A Chopped Radio Station

       

    Top 3 Tips for Running A Chopped Radio Station

    Sean Garvey sits down with DJ Smilez to discuss the top three tips for running a chopped radio station. Smilez explains both the technical and business side of running an online radio station and building a brand that will attract people to a platform dedicated to the chopped music subgenre of Hip-Hop.

    For more information about DJ Smilez
    https://www.blackvibes.com/sothrowdradio

    Follow Sean Garvey on IG: https://www.instagram.com/seangarveyatl

    To create your own app:
    https://www.bvmobileapps.com



    via: https://audiomack.com/bvmobileapps/song/top-3-tips-for-running-a-chopped-radio-statio


    Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious

    How DJs Can Break Into the Las Vegas Market

       

    How DJs Can Break Into the Las Vegas Market

    Sean Garvey sits down with CORE DJ's affiliate and Power 88 (KCEP 88.1-FM) own DJ Kelly J to discuss breaking into the Las Vegas market as a DJ and the effort into putting other Las Vegas DJs on the forefront. DJ Kelly J also provides insight on young female DJs making it in a male dominated industry and how her role in the organization, Girls Who Brunch Tour, coincides with her professional DJ career in Las Vegas.

    For more information about DJ Kelly J
    https://www.instagram.com/djkellyj

    Follow Sean Garvey on IG: https://www.instagram.com/seangarveyatl

    To create your own app:
    https://www.bvmobileapps.com

    🎧 Music by: J. Keys (Anonymous Records) - @jkeysmusic



    via: https://audiomack.com/bvmobileapps/song/how-djs-can-break-into-the-las-vegas-marke


    Send Blog   ·     Share on Facebook   ·     Bookmark on Delicious