profile
viewpoint
larryonoff larryonoff @OnelightApps

larryonoff/Charts 1

Beautiful charts for iOS/tvOS/OSX! The Apple side of the crossplatform MPAndroidChart.

larryonoff/Moya 1

Network abstraction layer written in Swift.

larryonoff/NYAlertViewController 1

Highly configurable iOS Alert Views with custom content views

larryonoff/AdaptySDK-iOS 0

SDK for growing mobile in-app purchases

larryonoff/aws-mobile-appsync-sdk-ios 0

iOS SDK for AWS AppSync.

larryonoff/aws-sdk-ios 0

AWS SDK for iOS. For more information, see our web site:

larryonoff/BetterSegmentedControl 0

An easy to use, customizable replacement for UISegmentedControl & UISwitch.

startedairbnb/ResilientDecoding

started time in 10 days

pull request commentadaptyteam/AdaptySDK-iOS

Extend model objects with CustomStringConvertible

@larryonoff can you add this file to SDK? The rest looks fine.

Sorry. I'm not sure I understand what you mean.

Adapty.podspec has pattern for source files in Classes folder, so that Package.swift.

larryonoff

comment created time in 12 days

push eventlarryonoff/AdaptySDK-iOS

Ilya Laryionau

commit sha d7cd32f9df0030dec34412759f1c1e55da0d4854

Remove duplicate key

view details

push time in 12 days

pull request commentadaptyteam/AdaptySDK-iOS

Extend model objects with CustomStringConvertible

@Skifcha done

larryonoff

comment created time in 13 days

push eventlarryonoff/AdaptySDK-iOS

Ilya Laryionau

commit sha 1404ec47277f02d8685d88ecc4e02d3e4de058fd

Revert "Update example project" This reverts commit fbfd4beac8fb8f2be6acfac929f3d2caf777bb2f.

view details

push time in 13 days

pull request commentadaptyteam/AdaptySDK-iOS

Extend model objects with CustomStringConvertible

@Skifcha sure. will do.

larryonoff

comment created time in 13 days

issue closedadaptyteam/AdaptySDK-iOS

Please extend Model Objects with CustomStringConvertible

Please extend Model Objects with CustomStringConvertible to simplify debugging.

Now it prints e.g. <Adapty.PurchaserInfoModel: 0x2832cbd80>.

closed time in 18 days

larryonoff

issue commentadaptyteam/AdaptySDK-iOS

Please extend Model Objects with CustomStringConvertible

closing PR in favor PR #8

larryonoff

comment created time in 18 days

issue commentadaptyteam/AdaptySDK-iOS

Please extend Model Objects with CustomStringConvertible

@Skifcha sure!

larryonoff

comment created time in 18 days

issue commentadaptyteam/AdaptySDK-iOS

Please extend Model Objects with CustomStringConvertible

@Skifcha Done. https://github.com/adaptyteam/AdaptySDK-iOS/pull/8

larryonoff

comment created time in 20 days

push eventlarryonoff/AdaptySDK-iOS

Ilya Laryionau

commit sha fbfd4beac8fb8f2be6acfac929f3d2caf777bb2f

Update example project

view details

push time in 20 days

create barnchlarryonoff/AdaptySDK-iOS

branch : custom-string-convertible

created branch time in 20 days

fork larryonoff/AdaptySDK-iOS

SDK for growing mobile in-app purchases

https://adapty.io

fork in 20 days

issue commentadaptyteam/AdaptySDK-iOS

Please extend Model Objects with CustomStringConvertible

Just implemented it myself. Please check. I can make pull request from it.

// MARK: - PaywallModel

extension PaywallModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "developerId": developerId,
            "variationId": variationId,
            "revision": revision,
            "isPromo": isPromo,
            "products": products,
            "visualPaywall": visualPaywall,
            "customPayload": customPayload
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}

// MARK: - ProductModel

extension ProductModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "vendorProductId": vendorProductId,
            "introductoryOfferEligibility": introductoryOfferEligibility,
            "promotionalOfferEligibility": promotionalOfferEligibility,
            "promotionalOfferId": promotionalOfferId,
            "localizedDescription": localizedDescription,
            "localizedTitle": localizedTitle,
            "price": price,
            "currencyCode": currencyCode,
            "currencySymbol": currencySymbol,
            "regionCode": regionCode,
            "subscriptionPeriod": subscriptionPeriod,
            "introductoryDiscount": introductoryDiscount,
            "subscriptionGroupIdentifier": subscriptionGroupIdentifier,
            "discounts": discounts,
            "localizedPrice": localizedPrice,
            "discounts": discounts,
            "localizedSubscriptionPeriod": localizedSubscriptionPeriod
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}

extension ProductModel.PeriodUnit: CustomStringConvertible {
    public var description: String {
        switch self {
        case .day:
            return "day"
        case .week:
            return "week"
        case .month:
            return "month"
        case .year:
            return "year"
        case .unknown:
            return "unknown"
        }
    }
}

extension ProductSubscriptionPeriodModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "unit": unit,
            "numberOfUnits": numberOfUnits
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}

extension ProductDiscountModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "price": price,
            "identifier": identifier,
            "subscriptionPeriod": subscriptionPeriod,
            "numberOfPeriods": numberOfPeriods,
            "paymentMode": paymentMode,
            "localizedPrice": localizedPrice,
            "localizedSubscriptionPeriod": localizedSubscriptionPeriod,
            "localizedNumberOfPeriods": localizedNumberOfPeriods
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}

extension ProductDiscountModel.PaymentMode: CustomStringConvertible {
    public var description: String {
        switch self {
        case .payAsYouGo:
            return "payAsYouGo"
        case .payUpFront:
            return "payUpFront"
        case .freeTrial:
            return "freeTrial"
        case .unknown:
            return "unknown"
        }
    }
}

// MARK: - PromoModel

extension PromoModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "promoType": promoType,
            "variationId": variationId,
            "expiresAt": expiresAt,
            "paywall": paywall
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}

// MARK: - PurchaserInfoModel

extension PurchaserInfoModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "paidAccessLevels": paidAccessLevels,
            "subscriptions": subscriptions,
            "nonSubscriptions": nonSubscriptions
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}

extension PaidAccessLevelsInfoModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "id": id,
            "isActive": isActive,
            "vendorProductId": vendorProductId,
            "store": store,
            "activatedAt": activatedAt,
            "renewedAt": renewedAt,
            "expiresAt": expiresAt,
            "isLifetime": isLifetime,
            "activeIntroductoryOfferType": activeIntroductoryOfferType,
            "activePromotionalOfferType": activePromotionalOfferType,
            "willRenew": willRenew,
            "isInGracePeriod": isInGracePeriod,
            "unsubscribedAt": unsubscribedAt,
            "billingIssueDetectedAt": billingIssueDetectedAt
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}

extension SubscriptionsInfoModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "isActive": isActive,
            "vendorProductId": vendorProductId,
            "store": store,
            "activatedAt": activatedAt,
            "renewedAt": renewedAt,
            "expiresAt": expiresAt,
            "startsAt": startsAt,
            "isLifetime": isLifetime,
            "activeIntroductoryOfferType": activeIntroductoryOfferType,
            "activePromotionalOfferType": activePromotionalOfferType,
            "willRenew": willRenew,
            "isInGracePeriod": isInGracePeriod,
            "unsubscribedAt": unsubscribedAt,
            "billingIssueDetectedAt": billingIssueDetectedAt,
            "isSandbox": isSandbox,
            "billingIssueDetectedAt": billingIssueDetectedAt,
            "vendorTransactionId": vendorTransactionId,
            "vendorOriginalTransactionId": vendorOriginalTransactionId
            
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}

extension NonSubscriptionsInfoModel: CustomStringConvertible {
    public override var description: String {
        let keysAndValues: [String: Any] = [
            "purchaseId": purchaseId,
            "vendorProductId": vendorProductId,
            "store": store,
            "purchasedAt": purchasedAt,
            "isOneTime": isOneTime,
            "isSandbox": isSandbox,
            "vendorTransactionId": vendorTransactionId,
            "vendorOriginalTransactionId": vendorOriginalTransactionId
        ].compactMapValues { $0 }

        return keysAndValues
            .map { "\($0.key): \($0.value)" }
            .joined(separator: ", ")
    }
}
larryonoff

comment created time in 21 days

issue commentadaptyteam/AdaptySDK-iOS

didReceiveUpdatedPurchaserInfo notifies that subscription is not active when it's active

@Skifcha I just tried steps to reproduce for Adapty version 1.7.0, as result everything works fine.

FYI. Steps to reproduce:

  1. Purchase any subscription.
  2. Wait till subscription renews.
  3. Restart debugger
larryonoff

comment created time in 21 days

issue commentadaptyteam/AdaptySDK-iOS

didReceiveUpdatedPurchaserInfo notifies that subscription is not active when it's active

@larryonoff hey, did you check "state" property in method callback? Callback calls two times – first with "state"=.cached, which delivers previously cached value; the second one is with "state"=.synced, which means data fully synced from server. If your data is sensitive and needs to be synced all the time, just look at the "state"=.synced and it should be enough.

Thanks for the reply. I don't see that PurchaserInfoModel or didReceiveUpdatedPurchaserInfo have state.

larryonoff

comment created time in 24 days

startedapple/swift-system

started time in 24 days

issue openedadaptyteam/AdaptySDK-iOS

didReceiveUpdatedPurchaserInfo notifies that subscription is not active when it's active

didReceiveUpdatedPurchaserInfo sends two notifications on app initialization:

  • first - that standard subscription is NOT active
  • then second, almost immediately - that standard subscription is active

expected behavior: one event that subscription is active when it's active

created time in 24 days

issue openedadaptyteam/AdaptySDK-iOS

Please extend Model Objects with CustomStringConvertible

Please extend Model Objects with CustomStringConvertible to simplify debugging.

Now it prints e.g. <Adapty.PurchaserInfoModel: 0x2832cbd80>.

created time in 24 days

startedapple/swift-syntax

started time in 24 days

startedapple/swift-crypto

started time in 24 days

startedapple/swift-numerics

started time in 24 days

startedapple/swift-nio

started time in 24 days

startedapple/swift-driver

started time in 24 days

startedapple/swift-argument-parser

started time in 24 days

startedapple/swift-atomics

started time in 24 days

issue commentadaptyteam/AdaptySDK-iOS

Main Thread Checker fails on Adapty.getPaywalls call from other that main thread

@AKyashkin thanks! The fix looks perfect.

larryonoff

comment created time in a month

issue openedadaptyteam/AdaptySDK-iOS

Main Thread Checker fails on Adapty.getPaywalls call from other that main thread

There's functions call-chain: Adapty.getPaywalls -> IAPManager.getPaywalls -> IAPManager.getPaywallsAndSyncProducts.

IAPManager.getPaywallsAndSyncProducts uses UIApplication under the hood. As result Adapty.getPaywalls call from other that main thread fails Main Thread Checker.

Expected behaviour: Adapty.getPaywalls can be called from any thread.

created time in a month

issue openedMetalPetal/MetalPetal

Cannot compile MetalPetal demo

See an error enclosed to the issue:

Screen Shot 2020-08-17 at 13 38 43

created time in 2 months

issue commentMetalPetal/MetalPetal

Operators to apply array of filters

Thank. Really helpful!

larryonoff

comment created time in 3 months

issue openedSCENEE/FloatingPanel

Fatal Exception: CALayerInvalidGeometry

CALayer position contains NaN: [nan nan]

Fatal Exception: CALayerInvalidGeometry
0  CoreFoundation                 0x185d3a364 __exceptionPreprocess
1  libobjc.A.dylib                0x184f80528 objc_exception_throw
2  CoreFoundation                 0x185d3a2ac -[NSException initWithCoder:]
3  QuartzCore                     0x189d86690 CA::Layer::set_position(CA::Vec2<double> const&, bool)
4  QuartzCore                     0x189d7863c -[CALayer setPosition:]
5  UIKit                          0x18f4fdc1c __44+[UIView(Animation) _stopAnimationWithUUID:]_block_invoke
6  UIKit                          0x18f229a14 +[UIView(Animation) performWithoutAnimation:]
7  UIKit                          0x18f4fda2c +[UIView(Animation) _stopAnimationWithUUID:]
8  UIKit                          0x18fef9a50 -[UIViewPropertyAnimator stopAnimation:]
9  FloatingPanel                  0x10551c150 FloatingPanelCore.handle(panGesture:) + 401 (FloatingPanelCore.swift:401)
10 FloatingPanel                  0x10551c6e8 @objc FloatingPanelCore.handle(panGesture:) (<compiler-generated>)
11 UIKit                          0x18f8b8cd0 -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:]
12 UIKit                          0x18f8bd2c4 _UIGestureRecognizerSendTargetActions
13 UIKit                          0x18f395aa8 _UIGestureRecognizerSendActions
14 UIKit                          0x18f24cc38 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:]
15 UIKit                          0x18f8a6b34 _UIGestureEnvironmentUpdate
16 CoreFoundation                 0x185ce1edc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
17 CoreFoundation                 0x185cdf894 __CFRunLoopDoObservers
18 CoreFoundation                 0x185cdfe50 __CFRunLoopRun
19 CoreFoundation                 0x185bffe58 CFRunLoopRunSpecific
20 GraphicsServices               0x187aacf84 GSEventRunModal
21 UIKit                          0x18f27f67c UIApplicationMain
22 inpreview                      0x104d8d0a0 main + 14 (IPVNavigatioImageButton.swift:14)
23 libdyld.dylib                  0x18571c56c start

created time in 3 months

issue openedMetalPetal/MetalPetal

Operators to apply array of filters

I have an array of MTIUnaryFilter. It would be great having operator that connects them all with MTIImage in a way below

        let lutFilter = MTIColorLookupFilter(...)

        let filters: [MTIUnaryFilter] = [
            adjustments.clarityFilter,
            adjustments.contrastFilter,
...
            adjustments.vibranceFilter
        ].compactMap { $0 }

        return FilterGraph.makeImage { output in
            if let lutFilter = lutFilter {
                image => lutFilter.inputPorts.inputImage

                lutFilter
                    => filters
                    => output
            } else {
               imag
                    => filters
                    => output
            }
      }

It also would be great to connect LUT filter in a shorter way, e.g.

                image
                    => lutFilter
                    => filters
                    => output

created time in 3 months

issue commentMetalPetal/MetalPetal

Is there any common ways to send data from shader function to MTIFilter back?

I think you can use MTIDataBuffer. A MTIDataBuffer can be binded to a shader parameter with type device T *, you can write the buffer in the shader. And you can safely pass this buffer to another filter.

You can also access the buffer's content on CPU using the unsafeAccess method. However, you must ensure all the GPU reads/writes to this buffer is completed. For example, after calling the waitUntilCompleted method of the MTIRenderTask.

Thank you for the answer!

Is there any existing filters / code in MetalPetal that I can check?

larryonoff

comment created time in 3 months

issue openedMetalPetal/MetalPetal

Is there any common ways to send data from shader function to MTIFilter?

Is there any common ways to send data from shader function to MTIFilter? I would like to implement some kind of https://github.com/FlexMonkey/ParticleCam/blob/master/ParticleCam/Shaders.metal

created time in 3 months

starteds1ddok/Alloy

started time in 3 months

pull request commentdanielgindi/Charts

Add gradient bars for BarChart [master branch]

@liuxuan30

1st is about accessibilityOrderedElements in the new code, I didn't see it. Did you just forget or because there are issues?

just pushed commit

2st is about the var nsuirgba, I need your input which is new, because you added two same var with different implementation. And I can't tell which is the right one.

nsuirgba implementation differs for macOS and iOS.

  • iOS uses UIColor.getRed, which returns success / not and only available for iOS .
  • macOS uses NSColor.getRed, which doesn't return any values (I'm not sure, but it may crash if input parameters doesn't fit RGB model).
larryonoff

comment created time in 3 months

Pull request review commentdanielgindi/Charts

Add gradient bars for BarChart [master branch]

 open class BarChartRenderer: BarLineScatterCandleBubbleRenderer                 context.fill(barRect)             }         }-        ++        if dataSet.drawBarGradientEnabled+        {+            drawGradientBars(context: context, dataSet: dataSet, buffer: buffer, matrix: valueToPixelMatrix)+        }+        else+        {+            drawDefaultBars(context: context, dataSet: dataSet, dateSetIndex: index, buffer: buffer)+        }+    }++    private func drawGradientBars(context: CGContext, dataSet: IBarChartDataSet, buffer: BarChartRenderer.Buffer, matrix: CGAffineTransform)+    {++        guard let gradientPositions = dataSet.gradientPositions else+        {+            assertionFailure("Must set `gradientPositions if `dataSet.drawBarGradientEnabled` is true")+            return+        }++        guard let boundingBox = buffer.rects.union() else { return }+        guard !boundingBox.isNull, !boundingBox.isInfinite, !boundingBox.isEmpty else { return }++        let drawBorder = dataSet.barBorderWidth > 0++        let gradientStart = dataSet.gradientEnd.isInfinite ?+            CGPoint(x: boundingBox.minX, y: boundingBox.minY) :+            dataSet.gradientEnd.applying(matrix)++        let gradientEnd = dataSet.gradientStart.isInfinite ?+            CGPoint(x: boundingBox.minX, y: boundingBox.maxY) :+            dataSet.gradientStart.applying(matrix)++        var gradientColorComponents: [CGFloat] = []+        var gradientLocations: [CGFloat] = []++        for position in gradientPositions.reversed()+        {+            let location = CGPoint(x: boundingBox.minX, y: position)+                .applying(matrix)+            let normalizedLocation =+                (location.y - boundingBox.minY) / (boundingBox.maxY - boundingBox.minY)+            switch normalizedLocation {+            case ..<0:+                gradientLocations.append(0)+            case 0..<1:+                gradientLocations.append(normalizedLocation)+            case 1...:+                gradientLocations.append(1)+            default:+                assertionFailure()+            }+        }++        for color in dataSet.colors.reversed()+        {+            guard let (r, g, b, a) = color.nsuirgba else {+                continue+            }+            gradientColorComponents += [r, g, b, a]+        }++        let baseColorSpace = CGColorSpaceCreateDeviceRGB()+        guard let gradient = CGGradient(+            colorSpace: baseColorSpace,+            colorComponents: &gradientColorComponents,+            locations: &gradientLocations,+            count: gradientLocations.count) else {+                return+        }++        for barRect in buffer.rects+        {+            context.saveGState()+            defer { context.restoreGState() }++            guard viewPortHandler.isInBoundsLeft(barRect.maxX) else { continue }+            guard viewPortHandler.isInBoundsRight(barRect.minX) else { break }++            context.beginPath()+            context.addRect(barRect)+            context.clip()+            context.drawLinearGradient(gradient, start: gradientStart, end: gradientEnd, options: [])++            if drawBorder+            {+                context.setStrokeColor(dataSet.barBorderColor.cgColor)+                context.setLineWidth(dataSet.barBorderWidth)+                context.stroke(barRect)+            }+        }

@liuxuan30 pushed commit. Hope that I did it correct.

larryonoff

comment created time in 3 months

push eventlarryonoff/Charts

Ilya Laryionau

commit sha e59ade133c3976ec19e3ebba7bd3c986bee4003e

Add accessibilityOrderedElements support

view details

push time in 3 months

more